【发布时间】:2013-05-28 21:39:19
【问题描述】:
正如标题所暗示的,我使用过winsock 和boost 插座。我在检测断开连接时遇到了难以置信的困难。
首先,我知道可以通过以下方式发现断线:
- recv() / async_read() 返回套接字错误或 0。
- send() / async_write() ... ... ...
- 客户端是否手动关闭、被中断/程序关闭 - 随便。
所以这里是问题场景:
我用 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.
这是我必须忍受的吗?我有点迷失了,因为我尽我所能检测断线……但它们仍然是个问题。
【问题讨论】:
-
你在 TCP 上实现了什么协议?它有协议规范吗?
-
当连接被异常终止/丢失时,操作系统无法知道它已经消失了一段时间,因此在此期间它不会报告错误,并缓冲输出数据等待让对等方接受数据。这就是socket-level keepalives和protocol-level pings发挥作用的地方。如果 keepalive/ping 超时并且无法及时响应,则无论其实际状态如何,都只需关闭套接字。
标签: c++ sockets networking boost disconnection