TCP socket如何判断连接断开

http://blog.csdn.net/zzhongcy/article/details/21992123

SO_KEEPALIVE是系统底层的机制,用于系统维护每一个tcp连接的。

心跳线程属于应用层,主要用于终端和服务器连接的检查。

即使SO_KEEPALIVE检测到连接正常,但并不能保证终端和服务器连接的正常。有一种情况,服务器进程死了,但它和客户端的tcp连接还连着(该连接由系统维护的)。

这就是SO_KEEPALIVE不能取代心跳线程的原因吧。

###############################

最近在做一个TCP采集程序,使用到C/S的结构。功能比较的简单,就是TCP采集程序作为服务器,信令采集设备作为客户端,客户端与服务器端之间建立长连接之后,开始发送信令报文给服务器。在服务器端使用多线程方式来处理每个客户端的socket连接,服务器端不主动断开链路,也没有心跳机制来维护连接的状态,客户端发送数据的时间也是不一定的,只要有采集到信令数据时才进行发送。在客户端socket断开后,服务器端应该能够知道并且释放socket资源。
     判断socket是否已经断开的方法是使用非阻塞的select方式进行socket检查,步骤如下:

1)设置接收到的socket为异步方式;

2)使用select()函数测试一个socket是否可读;

3)如果select()函数返回的值为1,但是使用recv()函数读取的数据长度为0,那么说明该socket已经断开。

4)如果recv()返回值小于等于0时,客户端的连接已经断开,但是还需要判断errno是否等于EINTR。如果errno=EINTR则说明recv()函数是由于程序接收到中断信号后返回的,socket连接应该还是正常,步应该close掉socket连接

注:对于阻塞socket的recv函数会在以下三种情况下返回值:

1)接收到数据时会返回;

2)程序接收到信号时返回-1,errno=EINTR;

3)Socket出现问题时,返回-1,具体的错误码请查看man recv;

4)一定要养成查看man说明,内容很详细,很有帮助。

这种方法经过长时间的测试证明是有效的,仅供大家参考。

此外,UNP卷一上有很多socket异常情况下的模拟解释,大家可以去阅读下。如果网络中间有多级路由,路由当掉等很多情况出现,所以建议程序中在应用层中加入心跳(heartbeat机制)和重连来维持连接的状态

TCP protocol has a timer to determine if the connection is abnormally closed. But this timeout value is very long by default and if you want to check this situation as soon as possible to improve performance, the best solution is to introduce a keepalive mechanism in application protocol design.

TCP协议有一个定时器来决定连接是否被异常关闭。但是该超时时间值缺省的情况下会非常长,如果你希望尽快的检查出这种状态改进性能,最好的方法就是在应用程序协议设计的时候引入keepalive(保持连接)机制。

########################################

最近在做一个服务器端程序,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 说明,很详细,很有帮助。
这种方法经过长时间测试后,是有效的。所以写出来让大家参考一下,请大家发表意见。

时间: 2024-10-10 09:10:13

TCP socket如何判断连接断开的相关文章

TCP连接在没有数据交互式判断连接断开

非阻塞模式下,建立连接没有调用send()和recv()进行数据交互的情况怎么判断服务端连接主动断开? 通过recv()函数,没有数据时返回-1,服务端断开返回0,通过返回0判断服务端是否断开 unsigned long  u32NonBlock = 1; if ( ioctlsocket(pDlg->m_s32Socket, FIONBIO, &u32NonBlock) )     // 非阻塞 { closesocket(pDlg->m_s32Socket); pDlg->m

Nginx 中 fastcgi_pass 监听端口 unix socket和tcp socket差

Nginx 中 fastcgi_pass 监听端口 unix socket和tcp socket差别 Nginx连接fastcgi的方式有2种:unix domain socket和TCP,Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信.与管道相比,Unix domain sockets 既可以使用字节流和数据队列,而管道通信则只能通过字节流.Unix domain sockets的接口和Internet socke

Tcp服务端判断客户端是否断开连接

今天搞tcp链接弄了一天,前面创建socket,绑定,监听等主要分清自己的参数,udp还是tcp的.好不容易调通了,然后就是一个需求,当客户端主动断开连接时,服务端也要断开连接,这样一下次客户端请求链接的时候才能成功链接. 然后就开始找各种方法.其中简单的是看recv()返回为0,表明断开了链接,但是recv函数始终返回SOCKET_ERROR,找不到原因............ 参考的方法: 下面来罗列一下判断远端已经断开的方法: 法一: 当recv()返回值小于等于0时,socket连接断开

socket 如何判断远端服务器的连接状态?连接断开,需重连

fluent-logger-java is a Java library, to record events via Fluentd, from Java application. https://github.com/fluent/fluent-logger-java 使用该sdk过程发现,tcp连接断开之后,该sdk的重连机制无效. 2018-01-26 12:36:25,620 ERROR [org.fluentd.logger.sender.RawSocketSender] - <org

socket.sendUrgentData判断网络远端是否断开连接

来自于 http://chenke1215.blog.163.com/blog/static/124414520103611222617/ 最近在开发中遇到一个问题,就是如何判断远端服务器是否已经断开连接,如果断开那么需要重新连接. 首先想到socket类的方法isClosed().isConnected().isInputStreamShutdown().isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接. 然后

JAVA 判断Socket 远程端是否断开连接

最近在做项目的时候,遇到这样一个问题,如何判断 Socket 远程端连接是否关闭,如果关闭的话,就要重建连接Socket的类提供了一些已经封装好的方法, 如  isClosed().isConnected().isInputStreamShutdown().isOutputStreamShutdown()等,在测试时发现,这些方法都是本地端的状态,无法判断远端是否已经断开连接. 其实在socket类中有一个方法sendUrgentData,它会往输出流发送一个字节的数据,只要对方Socket的S

TCP四次挥手(断开连接)(未完待续)

正常情况下,调用close(),其中产生的一个效果就是发送FIN. 断开为什么需要四次握手: TCP协议是一种面向连接的.可靠的.基于字节流的运输层通信协议.TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了:但是,这个时候主机1还是可以接受来自主机2的数据:当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的:当主机2也发送了FIN报文段时,这个时候就表示主

TCP/IP,http,socket,长连接,短连接

TCP/IP TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 在传输层中有TCP协议与UDP协议. 在应用层有:TCP包括FTP.HTTP.TELNET.SMTP等协议                  UDP包括DNS.TFTP等协议 短连接 连接->传输数据->关闭连接 HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接. 也可以这样说:短连接是指SO

TCP/IP,http,socket,长连接,短连接——小结(转)

概要: 之前对这几个概念有点糊涂,查阅了些资料,稍微概括下他们的区别吧.如有错误,请拍~~~ 先看图: TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.    在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议.    在传输层中有TCP协议与UDP协议.    在应用层有FTP.HTTP.TELNET.SMTP.DNS等协议. Socket是什么呢? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,一组接口,把复杂的T