(转)TCP连接异常断开检测
TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现。某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接。下面介绍一种方法来检测这种异常断开的情况
|
TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现。某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接。下面介绍一种方法来检测这种异常断开的情况 1) 在TCP协议中提供了KEEPALIVE检测。该选项使能后,在一个TCP连接上,若指定的一段时间内没有数据交换,则自动发送分节等待对方确认。 SO_KEEPALIVE : 该选项设置是否打开探测 2) 设定探测相关选项值 int keepalive = 1; // 打开探测 3) 设置套接字的属性 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof (keepalive) < 0) 一旦打开KEEPALIVE探测,当TCP连接异常断开后,对sockfd进行recv操作会返回-1,并且errno的值为ETIMEDOUT。 这样一来就可以很方便的在应用程序中检测TCP连接的情况,如果检测到异常断开最简单的处理就是关闭连接。 =================================== WinSock TCP keepalive的机理及使用 TCP 是面向连接的 , 在实际应用中通常都需要检测对端是否还处于连接中。如果已断开连接,主要分为以下几种情况: 对于第一种情况,很好判断,但是对于第二种情况,可能会要麻烦一些。在网上找到了一些文章,大致有以下两种解决方法: 为了方便起见,我这里采用 keepalive 机制,下面我就以 WinSock 上我实验得到的结果来大致讲一下其机理和使用方法。 首先说一下 keepalive 来判断异常断开的原理,其实 keepalive 的原理就是 TCP 内嵌的一个心跳包。 以服务器端为例,如果当前 server 端检测到超过一定时间(默认是 7,200,000 milliseconds ,也就是 2 个小时)没有数据传输,那么会 向client 端发送一个 keep-alive packet (该 keep-alive packet 就是 ACK 和当前 TCP 序列号减一的组合),此时 client 端应该为以下三种情况之一: 1. client 端仍然存在,网络连接状况良好。此时 client 端会返回一个 ACK 。 server 端接收到 ACK 后重置计时器,在 2 小时后再发送探测。如果 2 小时内连接上有数据传输,那么在该时间基础上向后推延 2 个小时。 了解了 keep alive 大致的原理,下来看看在程序中怎么用,怎么设置参数:
其中, setsockopt 设置了 keepalive 模式,但是系统对 keepalive 默认的参数可能不符合我们的要求,比如空闲 2 小时后才探测对端是否活跃,所以 WSAIoctl 函数通过 tcp_keepalive 结构体对这些参数进行了相应设置。 tcp_keepalive 这 个 结构体在 mstcpip.h 头文件中有定义:
这个结构体设置了空闲检测时间,及检测时重复发送的间隔时间。详细的可以查询 msdn :http://msdn.microsoft.com/en-us/library/dd877220(VS.85).aspx 。 按照 msdn 上的说法,这些参数也可以通过在注册表里设置,分别为: 另外,有些人可能已经发现了, tcp_keepalive 这 个结构体中没有对重试次数这个参数的设置,这个参数可以通过注册表来设置,具体位置为: HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxDataRetransmissions 关于在注册表中设置这几个参数,我在 XP 和 Server2008 系统中都没有找到, msdn 上说貌似只是支持 server 2003 ,我这里没有实验,具体不太清楚。 设置好 keepalive 以后,我们通过实验来看看当 client 异常退出或是网络断掉的情况下, keepalive 怎么通知我们异常断开的情况。这里采用 select 模式,实验环境为 XP 系统和 Win7 系统,几种情况返回值如下: 1. 正常断开 P.S. 网上有些文章中写的 WSAGetLastError() 得到的结果为 ETIMEDOUT ,我这里不太清楚为什么和我这里得到的不太一样。 另外,在实验中,我发现了一个和以前理解的不太相同的地方,在这里也记录下来: 对于程序异常退出的情况(这里所说的异常退出包括程序异常关闭、重启等情况,但不包括系统待机休眠),实际上在不开启 keepalive 的情况下也是可以检测到的 ,我这里测试得到在不开启 keepalive 的情况下,异常关闭 client 端程序, server 端 recv 函数会立即返回 SOCKET_ERROR , last error 同样 为 WSAECONNRESET 。但是对于网络断开及系统待机休眠的情况,则必须设置 keepalive 才能检测到,并且对于上述情况,当网络重新连接或者系统恢复后,SOCKET连接并不能恢复。 具体原因我这里也不太清楚,看到有一篇文章是这样写的:“异常关闭下, SOCKET 虚拟通路会被重设,远端正在接受的调用就都会失败”。不知道正确与否,感觉有一定的道理,暂时记录下来。 转自:http://www.rosoo.net/a/201505/17296.html?utm_source=tuicool |
(转)TCP连接异常断开检测的更多相关文章
- TCP连接异常断开检测(转)
TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...
- 针对TCP连接异常断开的分析
我们知道,一个基于TCP/IP的客户端-服务器的程序中,正常情况下,我会是启动服务器使其在一个端口上监听请求,等待客户端的连接:通过TCP的三次握手,客户端能够通过socket建立一个到服务器的连接: ...
- 4个实验,彻底搞懂TCP连接的断开
前言 看到这个标题你可能会说,TCP 连接的建立与断开,这个我熟,不就是三次握手与四次挥手嘛.且慢,脑海中可以先尝试回答这几个问题: 四次挥手是谁发起的? 如果断电/断网了连接会断开吗? 什么情况下没 ...
- wireshark抓包分析tcp连接与断开
其实对于网络通信的学习,最好还是能够自己抓到包详细地一下,不然只单单通过文字和图的描述印象不够深刻.本文通过实际的抓包操作来看一下tcp的连接与断开是怎样的. 首先需要去https://www.wir ...
- TCP连接异常:broken pipe 和EOF
本文介绍3种TCP连接异常的情况. 1.server端没有启动,client尝试连接 ./client dial failed: dial tcp 127.0.0.1:8080: connect: c ...
- socket选项自带的TCP异常断开检测
TCP异常断开是指在突然断电,直接拔网线等等情况下,如果通信双方没有进行数据发送通信等处理的时候,无法获知连接已经断开的情况. 在通常的情况下,为了使得socket通信不受操作系统的限制,需要自己在应 ...
- TCP连接与断开详解(socket通信)
http://blog.csdn.net/Ctrl_qun/article/details/52518479 一.TCP数据报结构以及三次握手 TCP(Transmission Control Pro ...
- 设置TCP_USER_TIMEOUT参数来判断tcp连接是否断开
[TOC] 1. bug描述 前段时间遇到这样的一个问题,openstack一个控制节点宕机后,在宕机后一段时间内创建的虚拟机,一直卡在创建中的状态.有的甚至要等到16分钟之后虚拟机才会切换到下一个状 ...
- 【转】TCP连接突然断开的处理方法
TCP是因特网中的传输层协议,使用三次握手协议建立连接,下面是TCP建立连接的全过程. TCP断开连接的过程:TCP四次挥手. TCP/IP 协议簇分层结构 数据链路层主要负责处理传输媒介等众多的物理 ...
随机推荐
- vs ComboBox显示多行
ComboBox,Drop List Type添加了多个数据,但是编译出来点下来按钮,只有一行. 惆怅 然后搜了下发现有人说: 在资源里面点向下箭头,把数据区拉长一点 然后才发现,原来资源里的Comb ...
- 【转】(五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components
原创至上,移步请戳:(五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components 4.Interaction Components 本节涵盖了处 ...
- linux下查看最后登陆的用户的信息
[root@oracle ~]# last -aroot pts/1 Wed Apr 1 10:35 still logged in 10.3.12.1输入命令last -a 把从何处登入系统的主机名 ...
- LeetCode: Search in Rotated Sorted Array 解题报告
Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...
- Python 调用datetime或者time获取时间的时候以及时间转换,最好设置一下时区 否则会出现相差8个小时的情况
在使用调用datetime或者time获取时间的时候以及时间转换,最好设置一下时区, 因为不同机器设置的时区不同,获取的时间可能就不对,正好我们使用的这两个服务器使用的都是东八区,所以没有问题,设置方 ...
- ASP.NET学习笔记(1)——VS自动引入命名空间快捷键
说明(2017-7-3 22:16:35) 1.在vs的“工具”->“选项”中,左侧树形菜单,“环境”下的“键盘”中设置快捷键. 在“显示命令包含”输入框内输入“显示智能标记”,找到“视图.显示 ...
- PostgreSQL ALTER TABLE中改变数据类型时USING的用法<转>
在修改表字段类型的时候使用Using来进行显示的转换类型. 原文说明: SET DATA TYPE This form changes the type of a column of a table ...
- windows已阻止此软件因为无法验证发行者怎么办
出现提示windows已阻止此软件因为无法验证发行者怎么解决?有的时候访问某些网站会出现类似的提示.导致不能正常运行某个插件,遇到这个问题一般是浏览器的安全级别设置太高了,没有允许脚本控件运行 设 ...
- linux 计划任务(十)
[教程主题]: 计划任务 [1]at 在windows系统中,windows提供了计划任务这一功能,在控制面板 -< 性能与维护 -< 任务计划, 它的功能就是安排自动运行的任务. 通过' ...
- linux rsync介绍(八)
[教程主题]:rsync [1] rsync介绍 Rsync(Remote Synchronize) 是一个远程资料同步工具,可通过LAN/WAN快速同步多台主机,Rsync使用所为的“Rsync演算 ...