【问题标题】:TCP ports in ErlangErlang 中的 TCP 端口
【发布时间】:2011-05-08 12:32:27
【问题描述】:

我正在使用 Erlang 编写一个 bittorrent 客户端。我在同一个问题上被困了 4 天。

我正在向所有对等点发送握手,每个对等点都有自己的 ip:port。

我使用 gen_tcp:connect 进行连接。

问题是我无法得到他们的回复。我做了很多研究并使用了一些程序来监控我的入站/出站连接。

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

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

我可以使用 inet:port 获取此端口号,但错误始终相同:正在使用的端口。 我明白为什么会出现错误,这仅仅是因为我尝试监听的端口已被 gen_tcp:connect 使用。我试图关闭 Socket 以释放端口,但什么也没有。

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

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

//弗兰克。

【问题讨论】:

  • 顺便说一句,为什么最近大家都想写bittorrent peers fpr erlang???
  • 这是大学的任务,Peer!

标签: tcp erlang bittorrent


【解决方案1】:

这里听起来有些不对劲,让我总结一下您要做什么:

  • 您使用的是 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 现在也在避免它。所以我强烈怀疑你不想这样做。

【讨论】:

  • BitTorrent 确实需要gen_tcp:listen,因为每个客户端也像服务器一样工作。端口号通常被定义为一个特定的端口号,因此您可以在防火墙中插入漏洞等等。
【解决方案2】:

Bittorrent 有两种方式可以互相连接:

  • 您的客户端发起与对等方的连接,这是gen_tcp:connect。建立后的连接是双向的,这个唯一的连接是您用于所有通信的。

  • 对等方连接回您的客户端。这是gen_tcp:listen 路径,后跟gen_tcp:accept。再次建立双向连接,然后您可以使用它。

您看到正在使用的端口可能是因为您试图在已有连接的“顶部”创建一个连接。了解一下 TCP 连接可能是值得的。

可行的解决方案是先假设您只连接到其他人而忽略入站连接。针对接受入站连接的测试客户端运行,一切都会正常工作。然后,当一种方法有效时,您可以将入站连接添加到您的代码中。请注意,握手是相似的,但有一些细微的差别。例如,连接器首先将 info_hash 发送给连接者(因此连接者可以在其当前服务的种子中查找 infohash)。

【讨论】:

  • 感谢您的回复,如果我没记错的话,我知道您是 etorrent 的作者。我知道 bottorrent 协议需要监听和连接。但是现在,我要做的就是发送握手并获得回复。所以我忽略了所有其他的东西。我还有一个显示所有 tcp 连接的程序,它告诉我我的消息是握手类型的。同行们实际上正在向我握手。但是我正在使用 gen_tcp:listen 来获得他们的回复,我认为这是错误的。我应该改用 gen_tcp:recv 吗?
  • 编辑,看来我已经解决了这个问题。我会尽快回复您。我必须清理代码。
  • 阅读 Peers 消息并研究 Erlang 中主动和被动套接字的区别。运行erl -man gen_tcp
猜你喜欢
  • 2010-11-17
  • 2011-01-23
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2017-03-04
相关资源
最近更新 更多