我一直在尝试使用C语言进行基本的客户端/服务器通信,我正在尝试确定检测断开连接的客户端的最佳方法。我知道如果我想要一个阻塞解决方案,我可以简单地转移到read()。然而,在非阻塞上下文中,尤其是在网络中断而不是干净的断开连接的情况下,read()仍然会及时检测断开的连接吗?
现在,我只是隔一段时间从客户端发送keep-alive消息,并在服务器端检查超时,我想知道是否有更干净的方法。
发布于 2015-11-21 06:51:56
无论采用哪种阻塞模式,如果对等方由于任何原因断开连接,一系列TCP send()
操作最终都将失败,并返回ECONNRESET
;如果对等方完全断开连接,则TCP recv()
将返回零。
发布于 2015-11-21 04:47:01
一般来说,您不能肯定地检测到未干净断开连接的客户端。
编辑:也就是说,没有通用的are_you_still_there()
函数,也没有办法实现一个您可以始终依赖的函数来快速地提供既不会漏报也不会误报的" no“响应。
如果您使用的是无连接网络协议(即UDP),则无法肯定地检测到客户端已永久消失。
编辑: TCP支持在接收方未确认接收的情况下自动重新传输数据。相同数据的多次重新传输是可能的,在这种情况下,(重新)传输之间的超时按指数增加。在没有确认的情况下达到阈值重传次数或阈值重传超时之后,TCP子系统将认为连接断开,但这可能需要几分钟甚至几十分钟,这取决于本地协议实现和参数。
如果read()
实现检测到连接中断(通过超时或远程对等方强制断开连接),则可以依靠TCP发出错误信号。然而,如果您的“及时”概念与TCP实现的概念有很大不同,那么要确保以“及时”的方式将这样的错误传递给应用程序可能是棘手的,甚至是不可能的。
人们通常通过使用edit:应用级超时来判断何时释放专用于服务客户端的资源,或者可能通过提供心跳信号或等效信号(基本上仍归结为超时)的更高级协议来处理该问题。
编辑以添加:应用层协议中的“你在那里吗”消息的实现可以提供一种从对等体请求响应的手段,以便能够测量超时和/或在连接否则将空闲的时间期间检测连接关闭。由于这或多或少相当于本地计算机从远程对等机请求心跳的一种方式,因此它与您已有的类似。
另一方面,它确实提供了一个框架,其中本地机器可以尝试向对等体发送未经请求的消息,而不会干扰应用程序。这样,如果TCP实现已经将连接标记为关闭,无论是因为TCP级超时还是因为另一端将其关闭,则此时将通知本地计算机关闭连接。
https://stackoverflow.com/questions/33839765
复制