当前位置: 首页 > news >正文

TCP keepAlive

 路上,有朋友说到服务端异常死掉,而客户端无法感知的情况。我说可以用KEEPLIVE去增加检测,刚好,网上有一文章写得很详细。

<以下是转>http://space.itpub.net/25259598/viewspace-684112

在一个正常的TCP连接上,当我们用无限等待的方式调用下面的Recv或Send的时候:

   ret=recv(s,&buf[idx],nLeft,flags);

   或

   ret=send(s,&buf[idx],nLeft,flags);

   如果TCP连接被对方正常关闭,也就是说,对方是正确地调用了closesocket(s)或者shutdown(s)的话,那么上面的Recv或Send调用就能马上返回,并且报错。这是由于closesocket(s)或者shutdown(s)有个正常的关闭过程,会告诉对方“TCP连接已经关闭,你不需要再发送或者接受消息了”。但是,如果是网线突然被拔掉,TCP连接的任何一端的机器突然断电或重启动,那么这时候正在执行Recv或Send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。这种情形解决的办法是启动TCP编程里的keepAlive机制。

    struct TCP_KEEPALIVE inKeepAlive = {0};
    unsigned long ulInLen = sizeof(struct TCP_KEEPALIVE);
    struct TCP_KEEPALIVE utKeepAlive = {0};
    unsigned long ulOutLen = sizeof(struct TCP_KEEPALIVE);
    unsigned long ulBytesReturn = 0;

    inKeepAlive.onoff=1;
    inKeepAlive.keepaliveinterval=5000; //单位为毫秒
    inKeepAlive.keepalivetime=1000;      //单位为毫秒
    ret=WSAIoctl(s, SIO_KEEPALIVE_VALS, (LPVOID)&inKeepAlive, ulInLen, 
                          (LPVOID)&outKeepAlive, ulOutLen, &ulBytesReturn, NULL, NULL);

   此处的keepalivetime表示的是TCP连接处于畅通时候的探测频率,一旦探测包没有返回,就以keepaliveinterval的频率发送,经过若干次的重试,如果探测包都没有返回,那么就得出结论:TCP连接已经断开,于是上面的Recv或Send调用也就能马上返回,不会无限制地卡住了。

  上图是对上面文字的说明。亮条之前,TCP处于畅通状态,KeepAlive是以1000毫秒(keepalivetime的值)的频率发送探测包,在发送到第32个探测包的时候,探测包没有返回,于是就以5000毫秒(keepalivetime的值)的频率发送探测包,重发几次后,探测包都没有返回,于是就得出结论:此TCP连接已经断开了!

 

对于Win2K/XP/2003,可以从下面的注册表项找到影响整个系统所有连接的keepalive参数:


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]

“KeepAliveTime”=dword:006ddd00
“KeepAliveInterval”=dword:000003e8
“MaxDataRetries”=”5″

 

  对于实用程序来说,2小时的空闲时间太长。因此,我们需要手工开启Keepalive功能并设置合理的Keepalive参数。在XP和WIN2003系统上,可以针对单独的socket来设置,但是在windows 2000,不能单独设置,如果设置,那么影响是整个系统的所有socket。

 

相关文章:

  • underscorcejs集合2(详情http://www.bootcss.com/p/underscore/#collections)
  • 修改 Linux /etc/profile 以后如何生效
  • 排序功能实现 jQuery实现排序 上移 下移
  • 细说WCF中的会话模式
  • 回声状态网络(ESN)基础教程
  • C# 序列化
  • VisualSVN 手动记录访问日志
  • JDBC(连接池) -- 02(I)
  • windows   8   OneNoteMX
  • 第二次作业-Steam软件分析
  • [面试] 组合(非递归)
  • Which garbage collection strategy is using
  • OutputCache造成页面响应内容类型为text/vnd.wap.wml的问题
  • windws 8 应用小技巧(11-15)
  • Mac禁用ipv6
  • 网络传输文件的问题
  • FineReport中如何实现自动滚屏效果
  • flask接收请求并推入栈
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • java2019面试题北京
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Python语法速览与机器学习开发环境搭建
  • supervisor 永不挂掉的进程 安装以及使用
  • 包装类对象
  • 搭建gitbook 和 访问权限认证
  • 警报:线上事故之CountDownLatch的威力
  • 跨域
  • 力扣(LeetCode)56
  • 两列自适应布局方案整理
  • 前端之React实战:创建跨平台的项目架构
  • 深度学习入门:10门免费线上课程推荐
  • 回归生活:清理微信公众号
  • 正则表达式-基础知识Review
  • #include到底该写在哪
  • $(selector).each()和$.each()的区别
  • (Git) gitignore基础使用
  • (蓝桥杯每日一题)love
  • (四)linux文件内容查看
  • (一)SpringBoot3---尚硅谷总结
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .htaccess 强制https 单独排除某个目录
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET DataGridView数据绑定说明
  • .Net Winform开发笔记(一)
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET开发人员必知的八个网站
  • /run/containerd/containerd.sock connect: connection refused
  • @EventListener注解使用说明
  • @WebServiceClient注解,wsdlLocation 可配置
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [IE编程] 多页面基于IE内核浏览器的代码示例
  • [leetcode]56. Merge Intervals归并区间
  • [LeetCode]-Pascal's Triangle III 杨辉三角问题