2010-11-11 76 views
3

我使用Erlang来编写一个bittorrent客户端。对于同样的问题,我被困了4天。Erlang的TCP端口

我发送握手给所有对等体,每个对等体都有自己的ip:port。

我使用gen_tcp:连接来连接。

问题是我无法得到他们的答复。我做了大量的研究,并使用一些程序来监视我的入站/出站连接。

对等体获取数据并将回复发送回我用来发送握手的端口。

明智的代码:get_tcp:connect选择一个端口并使用该端口将数据发送到对等端。对端回复该端口。但是,正如您在Erlang中所了解的那样,您需要使用gen_tcp:listen来获取回复连接,并且您需要指定一个端口。在我的情况下,我应该监听的端口是gen_tcp:connect返回的端口。

我可以使用inet:port得到这个端口号,但是错误总是一样的:使用中的端口。 我明白为什么我会得到这个错误,这只是因为我试图监听的端口已被gen_tcp:connect使用。我试图关闭Socket来释放端口但没有任何东西。

所以我的问题是:是否有可能在Erlang中以某种方式连接到对等端并将数据发送到端口,然后在该端口上侦听回复。如果没有,那么我必须以某种方式告诉同行将我的数据发回给我选择的端口。

欢迎来自所有爱尔兰大师的任何想法。 谢谢,

//弗兰克。

+0

顺便说一句为什么最近每个人都想写BitTrent的同龄人fpr erlang ??? – 2010-11-11 15:19:14

+0

这是作为一个大学的任务,同行! – 2010-11-11 16:46:26

回答

6

东西听起来错在这里,让我来总结一下你正在尝试做的:

  • 您使用的是TCP连接,不是UDP

  • 一个TCP连接是这样的:

    Erlang side: IP1:Port1 <----> Peer side IP2:Port2 
    
  • IP2:Port2是您传递给gen_tcp:connect的端口,IP1只是本地计算机上接口的IP,而Port1可能是一个短暂端口由您的机器上的TCP堆栈选择。

  • 如果对方来回复相同的连接上,你只会得到的数据作为

    {tcp, Socket, Data} 
    

    消息作为端口所有者(谁大概大道连接过程)。除非您使用被动模式:那么您必须调用gen_tcp:recv og获取数据。

  • 如果您正在调用gen_tcp:listen,则尝试打开另一个连接返回。有一些协议可以处理这类信息,例如FTP,但您必须使用另一个端口号(通常调用listen,然后获取端口号并通过现有连接将这些端口号发送给可连接到现有端口的客户端)。但几乎所有较新的协议都不再这样做了,因为它的混乱和需要有状态的防火墙。即使FTP现在也避免它。所以我强烈怀疑你不想这样做。

+0

BitTorrent *不需要'gen_tcp:listen',因为每个客户端也都像服务器一样。端口号通常被定义为特定的端口号,因此您可以在防火墙中插入漏洞。 – 2010-11-11 16:54:40

1

BT软件有两种方式可以同行相互连接:

  • 你的客户端发起连接到同级,这是gen_tcp:connect。建立的连接是双向的,并且这是您用于所有通信的唯一连接。

  • 对等体连接回您的客户端。这是gen_tcp:listen路径,然后是gen_tcp:accept。再次建立一个双向连接,然后使用。

您会看到使用端口,可能是因为您正尝试在已有连接的“顶部”创建连接。在TCP连接上读取一些信息可能是值得的。

一个可行的解决方案路径是从假设你只连接到其他人并忽略入站连接开始的。针对接受入站连接的测试客户端运行,并且一切都将工作。然后,您可以在一种方式下将入站连接添加到您的代码中。请注意握手是相似的,但有一些细微的差异。例如,连接器首先将info_hash发送给connectee(因此连接器可以查找它当前正在服务的种子中的infohash)。

+0

感谢您的回复,如果我没有错,我意识到您是etorrent的作者。我知道无论是监听还是连接都是Bottorrent协议所必需的。但是现在,我所要做的就是发送握手并回复。所以我忽略了其他所有东西。我也有一个程序,显示所有的TCP连接,它告诉我,我的消息是握手类型。同行们实际上正在向我发送他们的握手。但是我正在使用gen_tcp:听取他们的回复,我认为现在是错误的。我应该使用gen_tcp:recv吗? – Frank 2010-11-11 19:02:51

+0

编辑,看起来像我已经解决了这个问题。我会尽快回复您。我必须清理代码。 – Frank 2010-11-11 19:19:13

+0

阅读对等消息并研究Erlang中主动和被动套接字之间的区别。运行'erl -man gen_tcp'。 – 2010-11-11 19:36:04