首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  网络/通讯  |  ACE   


对方网络非正常断开检测方法


原作者:不详    源出处:不详    发布者:施昌权    发布类型:转载    发布日期:2008-08-26

        

        Windows下
        此处的”非正常断开”指TCP连接不是以优雅的方式断开,如网线故障等物理链路的原因,还有突然主机断电等原因
        有两种方法可以检测:
        1.TCP连接双方定时发握手消息
        2.利用TCP协议栈中的KeepAlive探测
        第二种方法简单可靠,只需对TCP连接两个Socket设定KeepAlive探测,所以本文只讲第二种方法在Linux,Window2000下的实现(在其它的平台上没有作进一步的测试)
        Windows 2000平台下
        头文件
        #include <mstcpip.h>
        //定义结构及宏
        struct TCP_KEEPALIVE {
                        u_longonoff;
                        u_longkeepalivetime;
                        u_longkeepaliveinterval;
        };

        1. tcp_keepalive live,liveout;  
        2. live.keepaliveinterval=500;
        3. live.keepalivetime=3000;
        4. live.onoff=TRUE;  
        5. int iRet = setsockopt(Socket,SOL_SOCKET,SO_KEEPALIVE,(char *)Opt,sizeof(int));  
        6. if(iRet == 0){
        7.
        8.         DWORD dw;
        9.
        10.         if(WSAIoctl(Socket,SIO_KEEPALIVE_VALS,&live,sizeof(live),&liveout,sizeof(liveout),&dw,NULL,NULL)== SOCKET_ERROR){
        11.  
        12.                 //Delete Client  
        13.   
        14.                 return;
        15.         }  
        16.    }  

        ACE下代码 //by rainfish    blog.csdn.net/bat603
        int Opt = 1;
        //在测试过程中,发现检测的次数是5次,即下面的设置中,从最近一次消息开始计算的10秒后,每次间隔5秒,连续发送5次,即35秒发现网络断了
        tcp_keepalive live,liveout;  
        live.keepaliveinterval=5000; //每次检测的间隔 (单位毫秒)
        live.keepalivetime=10000;  //第一次开始发送的时间(单位毫秒)
        live.onoff=TRUE;  
        int iRet = stream.set_option(SOL_SOCKET,SO_KEEPALIVE,&Opt,sizeof(int));  
        if(iRet == 0)
        {  
                DWORD dw;
                //此处显示了在ACE下获取套接字的方法,即句柄的(SOCKET)化就是句柄
                if(WSAIoctl((SOCKET)h,SIO_KEEPALIVE_VALS,&live,sizeof(live),&liveout,sizeof(liveout),&dw,NULL,NULL)== SOCKET_ERROR)
               {
                        //Delete Client  
                        return;  
                }  
        }  

 

        Linux平台下
        #include    "/usr/include/linux/tcp.h"
        #include "/usr/include/linux/socket.h"
        ////KeepAlive实现,单位秒
        //下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口
        int keepAlive = 1;//设定KeepAlive
        int keepIdle = 5;//开始首次KeepAlive探测前的TCP空闭时间
        int keepInterval = 5;//两次KeepAlive探测间的时间间隔
        int keepCount = 3;//判定断开前的KeepAlive探测次数
        if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)
        {
                ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("(%P|%t) setsockopt SO_KEEPALIVE error!\n")));
        }

        if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)
        {
                ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPIDLE error!\n")));
        }

        if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)
        {
                ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPINTVL error!\n")));
        }

        if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)
        {
                ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("(%P|%t)setsockopt TCP_KEEPCNT error!\n")));
        }

  

 

关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号