【发布时间】:2016-05-02 13:44:20
【问题描述】:
我尝试了官方的 tcp echo 服务器示例server 和client。使用netstat -ano | findstr TIME_WAIT,我可以看到客户端每次都会导致 TIME_WAIT,而服务器则完全断开连接。
有没有办法防止 TIME_WAIT 或 CLOSE_WAIT 让双方都完全断开连接?
【问题讨论】:
标签: c++ tcp boost-asio
我尝试了官方的 tcp echo 服务器示例server 和client。使用netstat -ano | findstr TIME_WAIT,我可以看到客户端每次都会导致 TIME_WAIT,而服务器则完全断开连接。
有没有办法防止 TIME_WAIT 或 CLOSE_WAIT 让双方都完全断开连接?
【问题讨论】:
标签: c++ tcp boost-asio
CLOSE_WAIT 是一个编程错误。本地应用程序已收到传入关闭,但尚未关闭此端。
TIME_WAIT 在双方完全断开连接后出现,并且仅持续几分钟。避免它的方法是成为接收第一个关闭的结束。通常你想在服务器上避免它,所以你首先关闭客户端。
【讨论】:
长时间挥之不去的 CLOSE_WAIT 确实是一个编程错误(操作系统执行连接关闭,但您的应用程序不记得及时释放套接字 - 或者根本不记得)。
然而,TIME_WAIT 并不是真正的例外情况。有必要在正常连接关闭期间对可能丢失最后一个 ACK 段的连接提供干净的关闭。如果没有它,FIN+ACK 段的重传将通过连接重置来响应,一些敏感的应用程序可能不喜欢它。
让 TIME_WAIT 状态的套接字数量较少的最常见方法是通过调整全局 OS 级别参数来全局缩短其持续时间。 IIRC,还有一种方法可以通过setsockopt() 在单个套接字上完全禁用它(但是我不记得是什么选项),但是您可能偶尔会向在连接关闭期间丢失数据包的对等方发送可能不需要的 RST 段。
至于为什么您只在连接的一侧看到它们,可能是在请求首先关闭连接的一侧。就是它发送第一个 FIN,接收到 FIN+ACK,然后发送最后一个 ACK。如果最后一个 ACK 丢失,它将再次收到 FIN+ACK,并且应该重新发送 ACK,而不是 RST。然而,另一方肯定知道当最后一个 ACK 到达时连接已经完全完成,然后就不需要在那个套接字上等待任何其他东西——如果有任何东西到达那个具有相同地址对的主机+ TCP 端口端点作为刚刚关闭的套接字,它应该是一个新的连接请求(在这种情况下可能会打开一个新的连接),或者它是一些 TCP 状态机违规(并且必须用 RST 响应,或者可能一些 ICMP 禁止消息)。
【讨论】:
c++ code还是Windows operating system?