我读到过关于使用SO_LINGER套接字选项通过将延迟时间设置为零来故意“暗杀”等待时间状态的文章。这本书的作者接着说,我们永远不应该这样做,一般来说,我们永远不应该干扰时间等待状态。然后,他立即建议使用SO_REUSEADDR选项绕过time-wait状态。
我的问题是,有什么不同?在这两种情况下,您都过早地终止了time-wait状态,并冒着接收重复段的风险。为什么一个是好的,另一个是坏的?
发布于 2009-02-28 21:26:00
我做了更多的阅读,这是我对发生的事情的理解(希望是正确的):
当您在设置了SO_REUSEADDR的套接字上调用close时(或者您的应用程序崩溃),将发生以下顺序:
,它将立即返回,而不指示是否发送了任何剩余数据。对等节点发送数据确认
在SO_LINGER时间设置为零的情况下关闭套接字时:
因此,除了将linger设置为0是一种黑客和糟糕的风格之外,它也是不礼貌的,因为它没有经历干净的连接关闭。
发布于 2009-02-25 21:45:27
TIME_WAIT绝对是正常的。它发生在本地端的TCP FIN和来自远程位置的TCP FIN ACK之后。在TIME_WAIT中,您只需等待任何丢失的数据包到达本地地址即可。然而,如果存在丢失或丢失的分组,则TIME_WAIT在再次使用该地址之前确保TTL或“生存时间”到期。
如果您使用SO_REUSEADDR,那么您基本上就是在说,我将假定没有流浪包。这在现代、可靠的TCP网络中变得越来越可能。尽管仍有可能,但可能性不大。
将SO_LINGER设置为0会导致启动异常关闭,也称为“关闭连接”。在这里,您不尊重TIME_WAIT并忽略丢失数据包的可能性。
如果您看到FIN_WAIT_1,则这可能会导致问题,因为远程位置尚未发送TCP FIN ACK来响应您的FIN。因此,由于网络分区或错误路由,进程被终止或TCP FIN ACK丢失。
当您看到CLOSE_WAIT时,您有一个问题,这里您正在泄漏连接,因为您在给定TCP FIN时没有发送TCP FIN ACK。
发布于 2011-03-09 01:35:45
我使用SO_REUSEADDR将通配符绑定()到一个本地端口,其他程序已经在该端口上打开了一个连接。事实证明,只要没有两个套接字同时尝试在相同的地址/端口组合上使用listen(),这种特殊用法就不会造成问题。
https://stackoverflow.com/questions/587961
复制相似问题