处理插座断开。提升/ Winsock

时间:2013-05-28 21:39:19

标签: c++ sockets networking boost disconnection

正如标题所示,我曾与winsock&提升插座。我在检测断线时遇到了难以置信的困难。

首先,我知道可以通过以下方式发现断开连接:

  1. recv()/ async_read()返回套接字错误或0。
  2. send()/ async_write()...... ......
  3. 客户是否手动关闭,中断/程序关闭 - 无论如何。
  4. 所以这是问题场景:

    我用closesocket()关闭了我的连接。客户端检测到断开连接 - 一切正常。

    我关闭程序 - 客户端无法检测到断开连接的可能性为50/50。出于某种原因,我的重叠IO WSARecv()不是保证检测。

    我杀了这个过程。机率增加到检测的80%。 But for the rest of the 20% - here's what's bothering me. I implemented a keep-alive ping mechanism which sends data to the server. Even if I killed the program - the server is still async_writing() to the connection - even though it's not detected or dead.

    这是我必须忍受的吗?我有点失落,因为我尽力检测断线......但它们仍然是一个问题。

1 个答案:

答案 0 :(得分:3)

TCP不保证只接收的一方可以检测到连接丢失。您在TCP之上实现的协议应该在其设计中考虑到这一点。如果没有,协议就会被破坏,你应该对设计它的人大声抱怨。

如果您自己设计协议,请不要跳过记录协议的步骤。这应该始终包括它是否支持应用程序级别的消息,它们如何构成框架,何时传输,何时检测到断开连接,任何超时等等。在没有实际设计的情况下实施的“关闭袖口”协议基本上注定要失败,即使它恰好工作,也永远无法维护,因为根本不可能确定它应该如何工作。

一旦你有了协议规范,至少可以通过以下简单步骤找出问题所在:

  1. 服务器是否遵循规范?如果没有,停止。服务器坏了。

  2. 客户是否遵循规范?如果没有,停止。客户端坏了。

  3. 停止。规范已经破裂。

  4. 没有规范,这些问题是无法回答的。以这种方式造成了很大的痛苦。