避免TIME_WAIT

时间:2009-12-18 22:27:37

标签: c macos networking

我正在尝试避免客户端中的TIME_WAIT。我连接然后设置O_NONBLOCK和SO_REUSEADDR。我调用read直到它返回0.当read返回0时,errno也是0.我将此解释为服务器关闭连接的标志。但是,如果我调用close,则套接字设置为TIME_WAIT,由netstat确认。

由于我与同一主机/端口建立了多个连接,因此我最终开始看到“正在使用的地址”错误(请参阅http://hea-www.harvard.edu/~fine/Tech/addrinuse.html)。

读取返回0后我应该关闭吗?如果不这样,文件描述符会被释放吗?

3 个答案:

答案 0 :(得分:6)

启动关闭连接的那一方是最终处于TIME_WAIT状态的一方。 read()返回0应该表示服务器首先关闭套接字,所以是 - 这应该意味着TIME_WAIT最终在服务器端,客户端通过LAST_ACK

在一天结束时,您无法避免TIME_WAIT州。即使您成功将其从客户端移动到服务器端,在(server host, server port, client host, client port)结束之前仍然无法重复使用TIME_WAIT元组(无论它在哪一侧)。

由于该方案的三个部分已在您的方案中修复(server hostserver portclient host),因此您实际上只有这些选项:

  • 尝试提供更多客户端端口。默认情况下,某些操作系统仅使用一小部分可用端口用于“临时端口”(在这方面我不确定OSX)。如果是这种情况,请查看是否可以通过操作系统中的配置调整来更改范围,或者让应用程序在循环中搜索带有bind() / connect()的工作端口,直到连接正常工作。

  • 通过在客户端上使用多个IP地址,扩展可用的client host值。您必须特别将应用程序bind()提供给其中一个IP地址。

  • 通过在服务器上使用多个端口和/或IP地址,扩展可用的server host / server port值。客户端需要选择一个连接(循环,随机等)。

  • 可能是最好的选择,如果它是可行的:重构您的协议,以便完成的连接不会关闭,但进入“空闲”状态,以便以后可以重新使用,而不是打开一个新的连接(如HTTP keep-alive)。

答案 1 :(得分:1)

稍后在同一页面上他们提到了SO_REUSEADDR。这就是你所需要的。 您肯定希望在返回零时关闭读取文件描述符。

答案 2 :(得分:0)

在客户端设置SO_REUSEADDR对服务器端没有帮助,除非它还设置了SO_REUSEADDR