当服务器关闭连接并且客户端同时发送一些数据时会发生什么?

What happens when a server closes the connection and the client sends some data at the same time?

我有一个用 C 编写的服务器,它会在连接闲置一段时间后关闭连接。我有一个问题(很少发生)。读取在客户端失败,并显示 Connection broken。我怀疑服务器正在关闭连接并且客户端正在同时发送一些数据。

考虑以下场景(A是服务器,B是客户端)

  1. B发起连接,AB之间的连接建立。
  2. B 处于空闲状态并且达到了空闲超时。
  3. A 发起关闭
  4. BA 收到 FIN 之前,它开始向 A
  5. 发送请求
  6. B发送请求后,会读取响应

由于A已经关闭连接,B无法读取。

我的问题是

  1. 这种情况可能吗?
  2. 如何处理客户端空闲超时?
  3. 如何正确关闭AB之间的连接(避免B在此过程中发送请求)。总之,如何自动关闭连接?

根据我仅有的基本网络经验...并假设您正在谈论像 TCP/IP 这样的面向连接的连接,而不是 UDP/IP 无连接。

  1. 当然可以。你无法避免它。

  2. 有多种方法可以做到这一点,但所有方法都包括: 在服务器超时之前从客户端发送一些东西。如果客户端没有数据要发送,就让它发送类似“生命迹象”的东西。这可能是一条空数据消息,这完全取决于您的应用程序协议。或者根据需要设置超时时间,包括一些余量。某些协议仅在允许空闲时间的 3 倍后超时。

  3. 您不能自动关闭连接,因为客户端和服务器是分开的。网络上的每个数据包都需要一些时间来传输,两者都可以在同一时刻开始发送,服务器关闭消息,客户端发送新的数据消息。您对此无能为力。

    您需要让客户端妥善处理这种情况。例如,它可以接受这样一个断开的连接并将其解释为已关闭。如果服务器在客户端空闲时关闭连接,您应该已经有所反应。

How to close the connection between A and B properly (avoid B sending request during the process).

  • 服务器检测到超时
  • 服务器向客户端发送超时检测消息
  • 服务器等待回复(如果超时,假设客户端死了)
  • 如果客户端从服务器收到超时检测,它会回复ACK(或类似的东西)
  • 如果服务器从客户端收到 ACK,则 'gracefully' 关闭连接
  • 从现在开始,Server 和 Client 都不应该 send/receive 任何消息(发送 ACK 后,不要立即从客户端关闭连接,坚持约定的超时时间 - 请参阅 setsockopt:SO_LINGER)

最重要的是,就像建议的其他答案一样,客户端应该在空闲时发送 心跳 (以避免超时检测)。