我尽量避免在客户那里等时间。我连接,然后设置o_nonblock,这样就可以重用adr。我调用read直到它返回0。当read返回0时,errno也是0。我将此解释为服务器已关闭连接的迹象。但是,如果我调用close,套接字将被设置为time_wait,由netstat确认。
由于我与同一主机/端口建立了许多连接,我最终开始看到“address in use”错误(请参见http://hea-www.harvard.edu/~fine/Tech/addrinuse.html)。
我应该在read返回0后调用close吗?如果我不释放文件描述符?
最佳答案
启动连接关闭的那一边是最终处于TIME_WAIT
状态的那一边。read()
返回0应该表示服务器首先关闭了套接字,所以是的-这应该意味着TIME_WAIT
结束于服务器端,而客户端通过LAST_ACK
。
在一天结束的时候,你不能避免一个TIME_WAIT
状态。即使您成功地将它从客户端移动到服务器端,在(server host, server port, client host, client port)
结束之前(不管它在哪一边),您仍然无法重用该TIME_WAIT
元组。
由于该元组的三个部分在您的方案中是固定的(server host
,server port
,client host
),因此您实际上只有这些选项:
尝试使更多的客户端端口可用。在默认情况下,有些操作系统只为“临时端口”使用一小部分可用端口(在这方面,我不确定OSX)。如果是这种情况,请查看是否可以在操作系统中通过配置调整更改范围,或者让应用程序在连接工作之前循环查找工作端口。
通过在客户端上使用多个IP地址,扩展可用的bind()
值的数量。但是,您必须将应用程序connect()
专门设置到这些IP地址中的一个。
通过使用服务器上的多个端口和/或IP地址,扩展可用的client host
/bind()
值的数量。客户端需要选择一个连接(循环、随机等)。
如果可行的话,可能是最好的选择:重构协议,这样完成的连接不会关闭,而是进入“空闲”状态,以便以后可以重新使用,而不是打开一个新的连接(如http keep alive)。
关于c - 避免TIME_WAIT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1931043/