tcp 服务端如何判断客户端断开连接

您所在的位置:网站首页 tcp断开连接过程中出现的状态 tcp 服务端如何判断客户端断开连接

tcp 服务端如何判断客户端断开连接

#tcp 服务端如何判断客户端断开连接| 来源: 网络整理| 查看: 265

tcp 服务端如何判断客户端断开连接

一篇文章:

最近在做一个服务器端程序,C/S结构。功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一条socket连接。这就涉及到一个问题,如果socket连接断开(异常,正常)后,我如何才能感知到?server端这边是绝对被动的,sever端不能主动断开连接。也没有连接链路维持包之类的。client端发送数据的时间也是不定的。在socket连接断开后, server要能够感知到并释放资源。 这个问题在思考测试,询问同事之后,找到了一个方法,可以做到这一点。 当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。 为了更好的判定socket是否断开,我判断当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR 。如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。 PS:对于堵塞socket的recv函数会在以下三种情况下返回: (1)recv到数据时,会返回。 (2)在整个程序接收到信号时,返回-1。errno = EINTR。//在程序的起始阶段,屏蔽掉信号的除外。部分信号还是屏蔽不掉的。 (3)socket出现问题时,返回-1.具体错误码看 man recv() (4)一定要看 man 说明,很详细,很有帮助。 这种方法经过长时间测试后,是有效的。所以写出来让大家参考一下,请大家发表意见。

参考:如何判断socket已经断开 - Prayer - C++博客

tcp会自动断开连接吗?

已经建立了TCP连接,并可能互通信息。但是如果长时间不进行信息的传递。这个TCP连接会自动断开吗? 如果能自动断开的话,这个时间大约是多少呢?

回答:TCP的保活定时器能够保证TCP连接一直保持,但是TCP的保活定时器不是每个TCP/IP协议栈就实现了,因为RFC并不要求TCP保活定时器一定要实现。 摘自《TCP/IP详解》卷1第23章:保活并不是T C P规范中的一部分。Host Requirements RFC提供了3个不使用保活定 时器的理由: (1) 在出现短暂差错的情况下,这可能会使一个非常好的连接释放掉; (2)它们耗费不必要的带宽;(3)在按分组计费的情况下会在互联网上花掉更多的钱。 然而,许多实现提供了保活定时器。 更具体的资料,请参阅RFC。

tcp/ip详解更全面的描述:

tcp保活定时器

23.1介绍

在一个空闲的(idle)TCP连接上,没有任何的数据流,许多TCP/IP的初学者都对此感到惊奇。也就是说,如果TCP连接两端没有任何一个进程在向对方发送数据,那么在这两个TCP模块之间没有任何的数据交换。你可能在其它的网络协议中发现有轮询(polling),但在TCP中它不存在。言外之意就是我们只要启动一个客户端进程,同服务器建立了TCP连接,不管你离开几小时,几天,几星期或是几个月,连接依旧存在。中间的路由器可能崩溃或者重启,电话线可能go down或者back up,只要连接两端的主机没有重启,连接依旧保持建立。

这就可以认为不管是客户端的还是服务器端的应用程序都没有应用程序级(application-level)的定时器来探测连接的不活动状态(inactivity),从而引起任何一个应用程序的终止。回忆在10.7结束,BGP每隔30秒就向对方发送一个应用程序探测。这是一个应用程序定时器(application timer),与TCP存活定时器不同。

然而有的时候,服务器需要知道客户端主机是否已崩溃并且关闭,或者崩溃但重启。许多实现提供了存活定时器来完成这个任务。

存活(keepalive)并不是TCP规范的一部分。在Host Requirements RFC罗列有不使用它的三个理由:(1)在短暂的故障期间,它们可能引起一个良好连接(good connection)被释放(dropped),(2)它们消费了不必要的宽带,(3)在以数据包计费的互联网上它们(额外)花费金钱。然而,在许多的实现中提供了存活定时器。

存活定时器是一个包含争议的特征。许多人认为,即使需要这个特征,这种对对方的轮询也应该由应用程序来完成,而不是由TCP中实现。一些人对这个话题表现了极大的热情,甚至达到宗教般的狂热。

如果两个终端系统之间的某个中间网络上有连接的暂时中断,那么存活选项(option)就能够引起两个进程间一个良好连接的终止。例如,如果正好在某个中间路由器崩溃、重启的时候发送存活探测,TCP就将会认为客户端主机已经崩溃,但事实并非如此。

一些服务器应用程序可能代表客户端占用资源,它们需要知道客户端主机是否崩溃。存活定时器可以为这些应用程序提供探测服务。Telnet服务器和Rlogin服务器的许多版本都默认提供存活选项。

个人计算机用户使用TCP/IP协议通过Telnet登录一台主机,这是能够说明需要使用存活定时器的一个常用例子。如果某个用户在使用结束时只是关掉了电源,而没有注销(log off),那么他就留下了一个半打开(half-open)的连接。在图18.16,我们看到如何在一个半打开连接上通过发送数据,得到一个复位(reset)返回,但那是在客户端,是由客户端发送的数据。如果客户端消失,留给了服务器端半打开的连接,并且服务器又在等待客户端的数据,那么等待将永远持续下去。存活特征的目的就是在服务器端检测这种半打开连接。

更多:tcp保活定时器_zhoujunyi的博客-CSDN博客

我的方法不一样,我用getsockopt来判断,还是蛮准确的 

int SocketConnected(int sock) { if(sock


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3