假设我正在运行一个简单的服务器并且已经accept()
从客户端编辑了一个连接.
告诉客户端何时断开连接的最佳方式是什么?通常情况下,客户端应该发送一个关闭命令,但如果它手动断开连接或完全失去网络连接怎么办?服务器如何检测或处理此问题?
在TCP中,只有一种方法可以检测到有序断开,即从read()/recv()/recvXXX()
读取时获取零作为返回值.
还有一种可靠的方法来检测断开的连接:写入它.在对断开的连接进行足够的写入之后,TCP将进行足够的重试和超时,以确定它已损坏并最终导致write()/send()/sendXXX()
返回-1,其errno/WSAGetLastError()
值为ECONNRESET,
或在某些情况下"连接超时".请注意,后者与"连接超时"不同,后者可能出现在连接阶段.
您还应设置合理的读取超时,并删除失败的连接.
这里的答案是关于ioctl()
和FIONREAD
无意义的竞争.所有这一切都告诉您当前在套接字接收缓冲区中有多少字节,可以无阻塞地读取.如果客户端没有向您发送任何不构成断开连接的五分钟内的任何内容,但它确实会导致FIONREAD
零.不一样的是:甚至没有关闭.
为了进一步扩展这一点:
如果您正在运行服务器,则需要使用TCP_KEEPALIVE来监视客户端连接,或者自己执行类似的操作,或者了解通过连接运行的数据/协议.
基本上,如果连接被杀死(即没有正确关闭),那么服务器在尝试向客户端写入内容之前不会注意到,这就是keepalive为您实现的.或者,如果您更好地了解协议,则无论如何都可以断开不活动超时.