当服务器关闭连接并且客户端同时发送一些数据时会发生什么?
What happens when a server closes the connection and the client sends some data at the same time?
我有一个用 C
编写的服务器,它会在连接闲置一段时间后关闭连接。我有一个问题(很少发生)。读取在客户端失败,并显示 Connection broken
。我怀疑服务器正在关闭连接并且客户端正在同时发送一些数据。
考虑以下场景(A是服务器,B是客户端)
B
发起连接,A
和B
之间的连接建立。
B
处于空闲状态并且达到了空闲超时。
A
发起关闭
- 在
B
从 A
收到 FIN
之前,它开始向 A
发送请求
B
发送请求后,会读取响应
由于A
已经关闭连接,B
无法读取。
我的问题是
- 这种情况可能吗?
- 如何处理客户端空闲超时?
- 如何正确关闭
A
和B
之间的连接(避免B
在此过程中发送请求)。总之,如何自动关闭连接?
根据我仅有的基本网络经验...并假设您正在谈论像 TCP/IP 这样的面向连接的连接,而不是 UDP/IP 无连接。
当然可以。你无法避免它。
有多种方法可以做到这一点,但所有方法都包括: 在服务器超时之前从客户端发送一些东西。如果客户端没有数据要发送,就让它发送类似“生命迹象”的东西。这可能是一条空数据消息,这完全取决于您的应用程序协议。或者根据需要设置超时时间,包括一些余量。某些协议仅在允许空闲时间的 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)
最重要的是,就像建议的其他答案一样,客户端应该在空闲时发送 心跳 (以避免超时检测)。
我有一个用 C
编写的服务器,它会在连接闲置一段时间后关闭连接。我有一个问题(很少发生)。读取在客户端失败,并显示 Connection broken
。我怀疑服务器正在关闭连接并且客户端正在同时发送一些数据。
考虑以下场景(A是服务器,B是客户端)
B
发起连接,A
和B
之间的连接建立。B
处于空闲状态并且达到了空闲超时。A
发起关闭- 在
B
从A
收到FIN
之前,它开始向A
发送请求
B
发送请求后,会读取响应
由于A
已经关闭连接,B
无法读取。
我的问题是
- 这种情况可能吗?
- 如何处理客户端空闲超时?
- 如何正确关闭
A
和B
之间的连接(避免B
在此过程中发送请求)。总之,如何自动关闭连接?
根据我仅有的基本网络经验...并假设您正在谈论像 TCP/IP 这样的面向连接的连接,而不是 UDP/IP 无连接。
当然可以。你无法避免它。
有多种方法可以做到这一点,但所有方法都包括: 在服务器超时之前从客户端发送一些东西。如果客户端没有数据要发送,就让它发送类似“生命迹象”的东西。这可能是一条空数据消息,这完全取决于您的应用程序协议。或者根据需要设置超时时间,包括一些余量。某些协议仅在允许空闲时间的 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)
最重要的是,就像建议的其他答案一样,客户端应该在空闲时发送 心跳 (以避免超时检测)。