如何检测BSDwebsocket断开连接连接断开

帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:75&分页:一曲肝肠断发信人: wuqing (叶子), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 14:23:22 2005), 转信 &&&& 【 在 hellguard (小四★你说你最爱丁香花⊙) 的大作中提到: 】
:& 客户端突然间断开(比如死机或者拔掉网线),服务器端如何判断与之对应&& :& 的tcp连接已经断开(即判断server中一个socket文件描述符是无效的),&& :& 可以不实时的检测到,只要我去测试时能发现就行了?&& :& 我开始时想用非阻塞方式read这个连接,但是read的话,只要没有数据可读,&& :& 就返回-1,所以没法判断。&& :& 测试时,不能影响客户端,即不能往客户端写没用的数据。&&&& :他那个办法真能解决你的原始需求?我没看出来可以啊。&& 基本可行 && :你这个需求现实版一下,A用nc -l -p 7474侦听一个端口,然后B机用nc -n A 7474&& :去连,突然,我拨掉了B到A之间的路由器上的一根网线,这个时候你想让A能发现B挂&& :了、不参与通信了。&&&& :首先,这个时候你不乱动A、B的话,这条TCP连接不算挂了,等你插上网线,一切就&& :都恢复了。那个socket仍算有效的。你的原始需求包含这种情况吗?&& 依然可以发送诊断包,但是无法接收。指定时间内连续没有收到客户端的诊断包,服务器端可以采取措施,如重新启动服务。如果插上网线一切恢复而没有诊断包超时的话,不正好又可以收到诊断包了吗?诊断包超时计数重新开始呀 && :其次,B是你完全不可控的,你不能假设B会发送什么,何时发送,可以接收什么,是&& :这个意思吗?&& 不是完全不可控,只是没有源代码,有DLL就可以封装,看楼主的意思是尽量不修改客户端 && :那我觉得真正可行的还就是前面有些人说的,超时机制。基于一个超时就认为挂了的&& :假设。select/poll什么的都成,到了某个超时无来自B的数据,就认为B挂了。&& 主要是超时时间不好设置?您说多长合适?而且也如您所说:“就认为B挂了”,只是认为而已。所以理论上如您所说,超时机制最适合,但是可能不会是TCP的超时机制转而采用应用超时机制。 && :可能你真正想问的是,B有可能正常情况下长时间不向A发送数据,你想将这种情况与&& :挂了区分开,是不是这才是你的原始需求?如果是这样,那只能具体到B、A之间的正&& :常通信都是如何约定的,然后在这种约定(实际就是上层协议实现了)中寻找办法,而&& :不能指望在TCP层找办法了。
对,除Windows 完成端口以外很难在TCP层找到这样的实现办法(还不影响性能),所以才需要采用类似与TCP三次握手协议的东西放到应用层,不是最好的选择,但是是一个可用的选择。 && 当然了,如果楼主把应用需求 描述更清楚,可能会出更多的好主意。 &&&& --
不管我们相隔多远,我们看到的都是同一个月亮! &&&& ※ 修改:·wuqing 於 Nov 18 14:25:29 修改本文·[FROM: 218.249.16.*]
※ 来源:·水木社区 ·[FROM: 218.249.16.*]
一曲肝肠断发信人: wuqing (叶子), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 14:29:49 2005), 转信 &&&& 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: 不是说不能改client吗
这个估计不是做作业,所以我是从实用的角度去讨论,而不是从纯粹的理论来解决
如果只从理论,那么就把WinSock2的一些优秀特性移植过来不就可以了吗?只是移植也没有那么简单啊,就像Unix的稳定性,虽然BSD等那么多开源的操作系统存在,但微软的windows就是没有Unix稳定呢? && 其实我提供的也只是一个参考方法而已,不是最佳解决方案。不用那么在意。 &&&& --
不管我们相隔多远,我们看到的都是同一个月亮! &&&& ※ 来源:·水木社区 ·[FROM: 218.249.16.*]
&发信人: LogIn.bbs@bbs. (游走), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 瀚海星云 (Fri Nov 18 15:02:30 2005)
转信站: NEWSMTH!news.newsmth.org!news2.happynet.org!bbsnews.!USTC && 根据lz对问题的描述
应该是不能改client,不能往client发多余的数据 && 【 在 -SPAM.no (叶子) 的大作中提到: 】
: 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: : 不是说不能改client吗
: 这个估计不是做作业,所以我是从实用的角度去讨论,而不是从纯粹的理论来解决
: 如果只从理论,那么就把WinSock2的一些优秀特性移植过来不就可以了吗?只是移植也没有那么简单啊,就像Unix的稳定性,虽然BSD等那么多开源的操作系统存在,但微软的windows就是没有Unix稳定呢?
: 其实我提供的也只是一个参考方法而已,不是最佳解决方案。不用那么在意。
&一曲肝肠断发信人: wuqing (叶子), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 15:16:20 2005), 转信 &&&& 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: 根据lz对问题的描述
: 应该是不能改client,不能往client发多余的数据
可以让客户端连接服务器以后主动发送,服务器可以根据是否定时收到客户端数据判断连接状态啊,在应用中要不要调用SendDiagnosisPack和要不要发送ResponseDiagnosisPack完全根据具体情况来啊 && 再一个,修改不修改client其实是可以协调的,即使合同上这样写,很多东西都是可以谈的,对不对?要实现这个看起来非常简单的功能(肯定是实时性方面的一些要求嘛)如果一定要改客户端的话,你认为客户会坚持说“绝对”不能改吗? && 但是我们确实可以就此问题一起讨论,找出一些好的解决办法来 &&&&&& --
不管我们相隔多远,我们看到的都是同一个月亮! &&&& ※ 来源:·水木社区 ·[FROM: 218.249.16.*]
小鱼儿.煋.名主有花发信人: sando (小鱼儿·笑), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 15:20:51 2005), 转信 && 通讯的问题,只通过改一方是很难让整体有本质提高的
【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: 根据lz对问题的描述
: 应该是不能改client,不能往client发多余的数据
&&&& -- && &&&&&&&&&&&&也不知怎的,小鱼儿突然觉得心里甜了起来,全身飘飘然,就好像&&
&&&&&&&&一跤跌进成堆的棉花糖里。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&但他立刻告诉自己:"江鱼,小心些,这糖里是有毒的。"他立刻想&&
&&&&&&&&把铁心兰往外推,不知怎的,却推不下手。&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.203.*]
&发信人: LogIn.bbs@bbs. (游走), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 瀚海星云 (Fri Nov 18 15:29:28 2005)
转信站: NEWSMTH!news.newsmth.org!news.!news.happynet.org!bbsnews.sd && 比方说,写一个代理服务器
... && 【 在 -SPAM.no (小鱼儿·笑) 的大作中提到: 】
: 通讯的问题,只通过改一方是很难让整体有本质提高的
: 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: : 根据lz对问题的描述
: : 应该是不能改client,不能往client发多余的数据
&&发信人: LogIn.bbs@bbs. (游走), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 瀚海星云 (Fri Nov 18 15:29:12 2005)
转信站: NEWSMTH!news.newsmth.org!bbsnews.!USTC && o && 【 在 -SPAM.no (叶子) 的大作中提到: 】
: 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: : 根据lz对问题的描述
: : 应该是不能改client,不能往client发多余的数据
: 可以让客户端连接服务器以后主动发送,服务器可以根据是否定时收到客户端数据判断连接状态啊,在应用中要不要调用SendDiagnosisPack和要不要发送ResponseDiagnosisPack完全根据具体情况来啊
: 再一个,修改不修改client其实是可以协调的,即使合同上这样写,很多东西都是可以谈的,对不对?要实现这个看起来非常简单的功能(肯定是实时性方面的一些要求嘛)如果一定要改客户端的话,你认为客户会坚持说“绝对”不能改吗?
: 但是我们确实可以就此问题一起讨论,找出一些好的解决办法来
&&发信人: duduzhu.bbs@bbs. (du ran之间,迸出了爱情的火花), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 瀚海星云 (Fri Nov 18 15:30:10 2005)
转信站: NEWSMTH!news.newsmth.org!news.happynet.org!bbsnews.!USTC && 娃哈哈哈哈哈哈
【 在 LogIn (游走) 的大作中提到: 】
: 比方说,写一个代理服务器
: 【 在 -SPAM.no (小鱼儿·笑) 的大作中提到: 】
: : 通讯的问题,只通过改一方是很难让整体有本质提高的
&一曲肝肠断发信人: wuqing (叶子), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 15:36:12 2005), 转信 &&&& 【 在 LogIn.bbs@bbs. (游走) 的大作中提到: 】
: 比方说,写一个代理服务器
&& 我觉得您不能这样去比方说,那是把简单的问题复杂化,不是解决问题的思路。
就事论事,你觉得写一个代理服务器麻烦一些还是...?
好好想想还有什么好的办法在Unix下实现连接状态检测吧,大家一起想想办法 && --
不管我们相隔多远,我们看到的都是同一个月亮! &&&& ※ 来源:·水木社区 ·[FROM: 218.249.16.*]
爱护牙齿发信人: yanghsu (最爱飞行), 信区: NetPRG
标&&题: Re: 请教,如何判断一个tcp连接已经断开
发信站: 水木社区 (Fri Nov 18 15:43:51 2005), 转信 && 看来只能在应用层协议加上链路测试,就跟ftp的idle类似 && 【 在 wuqing (叶子) 的大作中提到: 】
: 我觉得您不能这样去比方说,那是把简单的问题复杂化,不是解决问题的思路。
: 就事论事,你觉得写一个代理服务器麻烦一些还是...?
: 好好想想还有什么好的办法在Unix下实现连接状态检测吧,大家一起想想办法
: ...................
南帝补钙 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 211.99.152.*]
文章数:75&分页:&&&&&&&&&&&&&&&&&&
posts - 165,comments - 8,trackbacks - 0
  最近在做项目的时候,遇到这样一个问题,如何判断 Socket 远程端连接是否关闭,如果关闭的话,就要重建连接Socket的类提供了一些已经封装好的方法, 如 &isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,在测试时发现,这些方法都是本地端的状态,无法判断远端是否已经断开连接。
  其实在socket类中有一个方法sendUrgentData,它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节(在Java 中是抛出异常),而SO_OOBINLINE属性默认情况下就是关闭的。
  以下是示例代码仅供参考:
public class Nksocket extends Thread{
public String ip=//连接服务器的IP
public Integer port=//连接服务器的端口
private Socket socket=//套节字对象
private boolean close = // 关闭连接标志位,true表示关闭,false表示连接
private Integer sotimeout=1*1*10;//超时时间,以毫秒为单位
//------------------------------------------------------------------------------
public Nksocket(){
public Nksocket(String ip,Integer port){
setIp(ip);
setPort(port);
* 初始化socket对象
public void init(){
InetAddress address = InetAddress.getByName(getIp());
socket = new Socket(address,getPort());
socket.setKeepAlive(true);//开启保持活动状态的套接字
socket.setSoTimeout(sotimeout);//设置超时时间
close=!Send(socket,"2");//发送初始数据,发送成功则表示已经连接上,发送失败表示已经断开
}catch(UnknownHostException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
* 读数据线程
public void run() {
while(true){
//---------读数据---------------------------
close = isServerClose(socket);//判断是否断开
if(!close){//没有断开,开始读数据
String readtext = ReadText(socket);
if(readtext!=null && readtext.trim().length()&0){
System.out.println("读取数据:"+readtext);
//---------创建连接-------------------------
while(close){//已经断开,重新建立连接
System.out.println("重新建立连接:"+getIp()+":"+getPort());
InetAddress address = InetAddress.getByName(getIp());
socket = new Socket(address,getPort());
socket.setKeepAlive(true);
socket.setSoTimeout(sotimeout);
close = !Send(socket,"2");
System.out.println("建立连接成功:"+getIp()+":"+getPort());
}catch(Exception se){
System.out.println("创建连接失败:"+getIp()+":"+getPort());
* 发送数据,发送失败返回false,发送成功返回true
* @param csocket
* @param message
public Boolean Send(Socket csocket,String message){
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(message);
}catch(Exception se){
se.printStackTrace();
* 读取数据,返回字符串类型
* @param csocket
public String ReadText(Socket csocket){
csocket.setSoTimeout(sotimeout);
InputStream input = csocket.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(input));
char[] sn = new char[1000];
in.read(sn);
String sc = new String(sn);
}catch(IOException se){
* 判断是否断开连接,断开返回true,没有返回false
* @param socket
public Boolean isServerClose(Socket socket){
socket.sendUrgentData(0xFF);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
}catch(Exception se){
* @param ags
public static void main(String[] ags){
Nksocket nksocket = new Nksocket("127.0.0.1",8090);
nksocket.start();
//------------------------------------------------------------------------------
public String getIp() {
public void setIp(String ip) {
public Integer getPort() {
public void setPort(Integer port) {
this.port =
参考资料:
阅读(...) 评论()博客访问: 4217231
博文数量: 1287
博客积分: 12444
博客等级: 上将
技术积分: 12519
注册时间:
出淤泥而不染,濯清涟而不妖,中通外直,不蔓不枝,香远益清,亭亭净植,可远观而不可亵玩焉。
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
&&& 最近在做一个服务器端程序,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 说明,很详细,很有帮助。
&& &这种方法经过长时间测试后,是有效的。所以写出来让大家参考一下,请大家发表意见。
&& &我的方法不一样,我用getsockopt来判断,还是蛮准确的
int SocketConnected(int sock)
&&&&if (sock <= 0)
&&&&&&&&return 0;
&&&&struct tcp_info info;
&&&&int len = sizeof(info);
&&&&getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) & len);
&&&&if ((info.tcpi_state == TCP_ESTABLISHED)) {
&&&&&&&&//myprintf("socket connected\n");
&&&&&&&&return 1;
&&&&} else {
&&&&&&&&//myprintf("socket disconnected\n");
&&&&&&&&return 0;
tcp_info和TCP_ESTABLISHED在linux/tcp.h
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/config.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/sock.h>
http:&&&&&&&&&&&&&&&&//www.cse.scu.edu/~dclark/am_256_graph_theory/linux_2_6_stack/globals.html#index_t
int SocketConnected(int sock)
&&&&if (sock <= 0)
&&&&&&&&return 0;
&&&&struct tcp_info info;
&&&&int len = sizeof(info);
&&&&getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) & len);
&&&&if ((info.tcpi_state == TCP_ESTABLISHED)) {
//myprintf("socket connected\n");
&&&&&&&&return 1;
&&&&} else {
//myprintf("socket disconnected\n");
&&&&&&&&return 0;
&&& 目前主要有三种方法来实现用户掉线检测:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat线程。
&& &下面我就上面的三种方法来做一下介绍。
&& &(1)SO_KEEPALIVE 机制
&& &这是socket库提供的功能,设置接口是setsockopt API:
&& &BOOL bSet=TRUE;
&& &setsockopt(hSocket,SOL_SOCKET,SO_KEEPALIVE,(const char*)&bSet,sizeof(BOOL));
&& &根据MSDN的文档,如果为socket设置了KEEPALIVE选项,TCP/IP栈在检测到对方掉线后,
&& &任何在该socket上进行的调用(发送/接受调用)就会立刻返回,错误号是WSAENETRESET ;
&& &同时,此后的任何在该socket句柄的调用会立刻失败,并返回WSAENOTCONN错误。
&& &该机制的缺点也很明显:
&& &默认设置是空闲2小时才发送一个“保持存活探测分节”,不能保证实时检测!
&& &当然也可以修改时间间隔参数,但是会影响到所有打开此选项的套接口!
&& &关联了完成端口的socket可能会忽略掉该套接字选项。
&& &(2)SIO_KEEPALIVE_VALS 机制
&& &设置接口是WSAIoctl API:
DWORD dwError = 0L ;
tcp_keepalive sKA_Settings = {0}, sReturned = {0} ;
sKA_Settings.onoff = 1 ;
sKA_Settings.keepalivetime = 5500 ; // Keep Alive in 5.5 sec.
sKA_Settings.keepaliveinterval = 3000 ; // Resend if No-Reply
if (WSAIoctl(skNewConnection, SIO_KEEPALIVE_VALS, &sKA_Settings,
&&&&&&&&&&sizeof(sKA_Settings), &sReturned, sizeof(sReturned), &dwBytes,
&&&&&&&&&&NULL, NULL) != 0)
&&&&dwError = WSAGetLastError() ;
&&&& 实现时需要添加tcp_keepalive and SIO_KEEPALIVE_VALS的定义文件MSTCPiP.h
&&&& 该选项不同于SO_KEEPALIVE 机制的就是它是针对单个连接的,对系统其他的套接
&&&& 口并不影响。
&&&&&&& 针对完成端口的socket,设置了SIO_KEEPALIVE_VALS后,激活包由TCP STACK来负责。
&&&& 当网络连接断开后,TCP STACK并不主动告诉上层的应用程序,但是当下一次RECV或者SEND操作
&&&& 进行后,马上就会返回错误告诉上层这个连接已经断开了.如果检测到断开的时候,在这个连接
&&&& 上有正在PENDING的IO操作,则马上会失败返回.
&&&& 该机制的缺点:
&&&&&&&&&&&& 不通用啦。MS的API只能用于Windows拉。不过,优雅一些^_^.
(3)Heart-Beat线程
&&&&&&& 没说的。自己写一个后台线程,实现Heart-Beat包,客户端受到该包后,立刻返回相应的反馈 包。
&&& 该方法的好处是通用,但缺点就是会改变现有的通讯协议!
/* Net check Make sure you have not used OUT OF BAND DATA AND YOU CAN use OOB */
int netcheck(int fd)
&&&&int buf_size = 1024;
&&&&char buf[buf_size];
&&&&//clear OOB DATA
&&&&recv(fd, buf, buf_size);
&&&&if (send(fd, (void *)"\0", 1, MSG_OOB) < 0) {
&&&&&&&&fprintf(stderr, "Connection[%d] send OOB failed, %s", fd, strerror(errno));
&&&&&&&&return -1;
&&&&return 0;
//复制代码
&&&&/* Setting SO_TCP KEEPALIVE */
&&&&//int keep_alive = 1;//设定KeepAlive
&&&&//int keep_idle = 1;//开始首次KeepAlive探测前的TCP空闭时间
&&&&//int keep_interval = 1;//两次KeepAlive探测间的时间间隔
&&&&//int keep_count = 3;//判定断开前的KeepAlive探测次数
void set_keepalive(int fd, int keep_alive, int keep_idle, int keep_interval, int keep_count)
&&&&int opt = 1;
&&&&if (keep_alive) {
&&&&&&&&if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keep_alive, sizeof(keep_alive)) == -1) {
&&&&&&&&&&&&fprintf(stderr, "setsockopt SOL_SOCKET::SO_KEEPALIVE failed, %s\n", strerror(errno));
&&&&&&&&if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void *)&keep_idle, sizeof(keep_idle)) == -1) {
&&&&&&&&&&&&fprintf(stderr, "setsockopt SOL_TCP::TCP_KEEPIDLE failed, %s\n", strerror(errno));
&&&&&&&&if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keep_interval, sizeof(keep_interval)) == -1) {
&&&&&&&&&&&&fprintf(stderr, "setsockopt SOL_tcp::TCP_KEEPINTVL failed, %s\n", strerror(errno));
&&&&&&&&if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void *)&keep_count, sizeof(keep_count)) == -1) {
&&&&&&&&&&&&fprintf(stderr, "setsockopt SOL_TCP::TCP_KEEPCNT failed, %s\n", strerror(errno));
阅读(8563) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。(笔记)Linux服务器中判断客户端socket断开连接的方法
时间: 22:15:22
&&&& 阅读:2936
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&下面来罗列一下判断远端已经断开的方法:(转自http://blog.csdn.net/god2469/article/details/8801356)
当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
& struct tcp_&& int len=sizeof(info);&&&getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);&& if((info.tcpi_state==TCP_ESTABLISHED))& 则说明未断开& else 断开
若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。
int keepAlive = 1; // 开启keepalive属性int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测&int keepInterval = 5; // 探测时发包的时间间隔为5 秒int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误
自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/tdyizhen1314/p/4324441.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!2011年9月 C/C++大版内专家分月排行榜第二2011年4月 C/C++大版内专家分月排行榜第二2010年11月 C/C++大版内专家分月排行榜第二
2011年6月 C/C++大版内专家分月排行榜第三
2011年11月 专题开发/技术/项目大版内专家分月排行榜第一2011年10月 专题开发/技术/项目大版内专家分月排行榜第一2011年9月 专题开发/技术/项目大版内专家分月排行榜第一2011年8月 专题开发/技术/项目大版内专家分月排行榜第一2011年7月 专题开发/技术/项目大版内专家分月排行榜第一2011年6月 C/C++大版内专家分月排行榜第一
2011年7月 C/C++大版内专家分月排行榜第二2011年5月 专题开发/技术/项目大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 socket 断开 检测 的文章

 

随机推荐