假设我正在运行一台简单的服务器,并通过accept()命令从客户端建立了一个连接。
判断客户端何时断开连接的最佳方法是什么?正常情况下,客户端应该发送close命令,但如果手动断开连接或完全断开网络连接怎么办?服务器如何检测或处理此问题?
发布于 2008-11-12 09:07:01
select (设置了读掩码)将返回带信号的句柄,但是当您使用ioctl*检查等待读取的字节数时,它将为零。这是插座已断开连接的标志。
这是关于检查客户端是否断开连接的各种方法的很好的讨论:Stephen Cleary, Detection of Half-Open (Dropped) Connections。
*对于Windows,请使用ioctlsocket。
发布于 2013-07-16 06:31:34
在TCP中,只有一种方法可以检测有序断开,那就是在读取时从read()/recv()/recvXXX()获取0作为返回值。
只有一种可靠的方法来检测断开的连接:写入连接。在对断开的连接进行足够多的写入后,TCP将进行足够的重试和超时以知道它已经断开,并最终导致write()/send()/sendXXX()返回-1并返回errno/WSAGetLastError()值ECONNRESET,,或者在某些情况下返回“connection timed timed”。请注意,后者不同于“连接超时”,后者可能发生在连接阶段。
您还应该设置一个合理的读取超时,并丢弃失败的连接。
关于ioctl()和FIONREAD,这里的答案是竞争无稽之谈。所要做的就是告诉您套接字接收缓冲区中当前有多少字节,可以在不阻塞的情况下进行读取。如果客户端在五分钟内没有向你发送任何东西,这并不构成断开,但它确实会导致FIONREAD为零。不是一回事:甚至不是很接近。
发布于 2008-11-12 11:41:13
在此基础上进行更多扩展:
如果您正在运行服务器,则需要使用TCP_KEEPALIVE监视客户端连接,或者自己执行类似的操作,或者了解在连接上运行的数据/协议。
基本上,如果连接被终止(即没有正确关闭),那么服务器不会注意到,直到它尝试向客户端写入一些东西,这就是keepalive为您实现的。或者,如果您更了解协议,则可以在不活动超时时断开连接。
https://stackoverflow.com/questions/283375
复制相似问题