即使有许多临时端口可用,connect()之前的bind()可能会返回EADDRNOTAVAIL

时间:2015-11-10 17:16:00

标签: linux sockets tcp

(已在Centos 6.5和Centos 7上测试过)

如果在linux中的connect()之前用INADDR_ANY和0端口调用bind()那么bind()的临时端口 选择可能与已建立的连接或TIME_WAIT中的连接冲突,connect()将返回EADDRNOTAVAIL。这是使用SO_REUSEADDR设置的套接字。 如果你在没有bind()的情况下调用connect(),就不会发生这种情况,因为connect()有它 自己(更复杂)选择短暂端口的方法。

这似乎与此处的讨论一致:

http://mail-archives.apache.org/mod_mbox/trafficserver-dev/201210.mbox/%3C001601cda670 $ fc59e470$f50dad50$@yooser.com%3E

在这里:

http://aleccolocco.blogspot.com/2008/11/ephemeral-ports-problem-and-solution.html

我已经看到这种情况发生在高负载下,只有少数现有已建立的连接 到目的地IP,所以这并不是关于使用所有可用的临时端口 或更改可用的临时端口范围。

简单的解决方法(如apache列表中所讨论的)是之前不调用bind() connect(),这样connect()的临时端口选择就更复杂了 用过的。

但这并不总是可行的。如果您的应用程序可选择允许配置,该怎么办 显式端口绑定到传出连接或IP池?

还有其他解决方法吗?

1 个答案:

答案 0 :(得分:0)

  

如果您的应用程序可选地允许配置显式端口以绑定到传出连接或IP池,该怎么办?

运气不好。你无能为力。

bind()不知道您要连接的内容(如果有的话),因此在分配时无法考虑TCP 4元组的远程部分端口号。由于同样的原因,它也不知道连接后本地IP地址是什么,所以它也不能考虑到这一点。