【问题标题】:how to close a tcp connection if FIN/ACK doesn't get a ACK response?如果 FIN/ACK 没有收到 ACK 响应,如何关闭 tcp 连接?
【发布时间】:2013-04-27 20:37:38
【问题描述】:

在一个用 Linux C 编写的 tcp 程序中 我想关闭一个 tcp 连接 我用close(sockfd) 我注意到这个函数将向另一个对等方发起一个 FIN/ACK 数据包 但是如果由于网络问题或 tcp 序列号不一致,其他对等方没有响应 ACK(例如,其他对等方的 tcp 堆栈崩溃) 然后似乎tcp连接无法关闭 它将始终处于 FIN_WAIT1 状态

如何处理? 这种情况下如何关闭tcp连接?

【问题讨论】:

  • 然后关闭部分将再次尝试发送FIN,然后再发送几次,直到最终超时,close 返回错误。
  • 在我看来close()不是阻塞式的,所以调用后无法返回错误。如何得到错误?
  • @user1944267 套接字是阻塞的还是非阻塞的?
  • 所以你的意思是close()的行为取决于套接字是否阻塞,如果不是,close()不会返回-1?
  • close() 在阻塞或非阻塞模式下都是异步的,除非您设置了延迟超时,在这种情况下,它要么阻塞直到超时,要么(可能)设置 errno = EAGAIN 如果必填。

标签: networking tcp network-programming


【解决方案1】:

TCP 处理它。你不必处理它。你不能处理它。

【讨论】:

  • 这实际上是错误的。 至少有两种方法可以解决这个问题:调整 TCP 堆栈,以便 TCP 会话更快超时或在应用程序级别超时通过使用setsockopt()SO_LINGER实际上错误的答案是您应该对其投反对票的原因。
【解决方案2】:

默认情况下,这由 TCP 实现根据与系统相关的系统范围的配置参数透明地处理。

这可以通过使用setsockopt() 设置SO_LINGER 套接字选项来覆盖,在这种情况下,对close() 的调用会阻塞,直到达到指定的超时时间。

编辑:我应该补充一点,如果目标是添加一些错误处理,例如记录一条错误消息,说明另一端可能未收到某些数据,则大多数时候使用 SO_LINGER 才值得麻烦。

【讨论】:

  • SO_LINGER 与它无关。它会导致 close() 阻塞,直到挂起的数据和传出的 FIN 被刷新,直到达到提供给 setsockopt()指定超时,而不是 '配置超时',它不需要 FIN 被 ACK'd。
  • 你说得对,我应该写“指定”而不是“配置”。但是...由于如此简单的措辞问题,您对这个答案投了反对票?您现在应该知道,对于此类案例,每个答案下都有一个edit 链接。 顺便说一句,在我看来,不再等待 ACK 正是 OP 想要做的。
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2013-08-11
  • 2016-04-27
  • 1970-01-01
相关资源
最近更新 更多