HTTP的RST包与WinHttp延迟关闭TCP连接
一、RST包也常见于断开TCP连接
几个月前用wireshark抓HTTP包发现有的网络通信在结束的时候没有使用四次握手,而是直接使用RST包。如:
在TCP协议中RST表示复位,用来异常的关闭连接。在发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。“异常的关闭连接”是很常见的事情,特别是在使用WinHttp时。
关闭TCP连接除了常见的四次握手之外,还有发送RST包的方式。下边是使用libcurl做的post测试,post成功时正常关闭,否则异常关闭。
结束TCP:四次握手图
结束TCP:发RST包图
二、WinHttp延迟关闭TCP连接
写一个简单的及时退出的控制台WinHttp Demo,可以抓包发现客户端是使用RST包结束连接,而且结束连接的时间不是在WinHttpCloseHandle的时候,而是在控制台程序退出的时候。
WinHttp有一个延迟关闭TCP连接的策略,这样做的目的是为了复用TCP连接。实际测试的时候发现调用了WinHttpCloseHandle后连接没有关闭,接下来如果继续往服务器发送数据,使用的是同一个TCP连接。不知道何时WinHttp会主动触发四次握手,网络上没找到这部分资料,开发者不需要关心。从MSDN问答区找到的资料:“WinHttp底层使用的是连接池,如果连接是由连接池自身关闭的,则会有FIN/ACK,否则就是RST包,跟客户端何时、是否调用了WinHttpCloseHandle没有关系。”,这么说的话,可以猜想,连接池是进程级别的,当进程退出时,连接池“匆忙”的让每一个连接发出了RST包,告诉服务器连接关闭了,说到这儿可能会想到RST包可能丢弃了,没关系,服务器本身有监控策略,譬如我遇到的就有:1分钟无通信,服务器主动触发四次握手关闭连接。延迟关闭是WinHttp库自身为了复用TCP连接而做的策略,因为这种策略而导致发送RST包。
另外,WinHttp中还有一个 TcpTimedWaitDelay的逻辑,但应该跟RST包没有什么关系,它是连接关闭多久之后TCP能释放资源并复用,是关闭之后的事情。我尝试修改了注册表HKLM\System\CurrentControlSet\Services\Tcpip\Parameters中TcpTimedWaitDelay的值,并不影响WinHttp发送RST包或者四次握手所需要的时间(测试的时候等的时间超过了1分钟,虽然我把TcpTimedWaitDelay修改为30秒了)。
本文: http://www.cnblogs.com/cswuyg/p/3516417.html
三、相关资料
1、有人询问了为什么WinHttp关闭连接不是使用四次握手: http://social.msdn.microsoft.com/Forums/vstudio/en-US/e10ee4f4-c4fe-4b34-87b3-03fb7d491376/winhttpclosehandle-half-duplex-close?forum=windowssdk
2、RST包出现场景介绍:http://my.oschina.net/costaxu/blog/127394
3、TCP关闭连接后资源不及时释放:"TCP does not release a connection or reuse its resources until the connection has remained closed for a period specified by the value of the TcpTimedWaitDelayentry" http://technet.microsoft.com/en-US/library/cc938178
HTTP的RST包与WinHttp延迟关闭TCP连接的更多相关文章
- golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期
欢迎访问我的个人网站获取更佳阅读排版 golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期 | yoko blog (https://pengrl.com/p/47401/) 本篇文章部 ...
- muduo 的 shutdown() 没有直接关闭 TCP 连接?
http://blog.csdn.net/Solstice/article/details/6208634 今天收到一位网友来信: 在 simple 中的 daytime 示例中,服务端主动关闭时调用 ...
- 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景
欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...
- 什么是RST包,什么是三次握手,什么是四次握手 ---请进
一.RST包.本人学习后总结:RST包用于强制关闭TCP链接. TCP连接关闭的正常方法是四次握手.但四次握手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可 ...
- TCP协议RST:RST介绍、什么时候发送RST包
TCP协议RST:RST介绍.什么时候发送RST包 RST标示复位.用来异常的关闭连接. 1. 发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区中的包,发送RST. 2. 而接收端收 ...
- TCP连接的关闭
原文地址:http://lib.csdn.net/article/computernetworks/17264 TCP连接的关闭有两个方法close和shutdown,这篇文章将尽量精简的说明它们 ...
- TCP连接的状态与关闭方式及其对Server与Client的影响
TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...
- Linux 内核协议栈之TCP连接关闭
Close行为: 当应用程序在调用close()函数关闭TCP连接时,Linux内核的默认行为是将套接口发送队列里的原有数据(比如之前残留的数据)以及新加入 的数据(比如函数close()产生的FIN ...
- TCP连接的状态与关闭方式,及其对Server与Client的影响
1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态, ...
随机推荐
- 使用QQ邮箱发送email(Python)
实际开发过程中使用到邮箱的概率很高,那么如何借助python使用qq邮箱发送邮件呢? 代码很简单,短短几行代码就可以实现这个功能. 使用到的模块有smtplib和email这个两个模块,关于这两个模块 ...
- javascript中三种典型情况下this的含义
this本意:基于函数的执行环境绑定. 1)一般函数内部,返回的是window(作用域链中的第二层全局作用域) function test() { return this; } alert(test( ...
- LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
同时安装了VS2012和VS2010,用VS2010 时 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 问题说明:当安装VS2012之后 ...
- Ambari组件黄色预警
Ambari组件黄色预警 组件上为黄色问号,代表心跳丢失,解决如下: 1. 查看个节点之间是否可以相互通信,若ssh连接不上,有可能是该节点关机了,没有打开,手动开启该节点,再次验证是否可互通. 2 ...
- 取消TableViewCell选中状态的外观变化
tabelViewcell 使用Xib创建自定义外观的时候,在tableview选中的时候,cell的外观会发生变化,在定义Xib中如下图将选中的外观状态取消掉 也有其他选项,可以选择控制选中的时候的 ...
- Flume_企业中日志处理
企业中的日志存放_1 201611/20161112.log.tmp 第二天文件变为20161112.log与20161113.log.tmp 拷贝一份flume-conf.properties.te ...
- 2016NOIP总结
从暑假开始学OI到现在,也已经过了4个月.说实话真是快啊...感觉没学什么东西就要去比赛了.怎么说呢,感觉自己真的是个菜鸡啊为什么就要去比赛呢.当初来到这里,是凭着兴趣来的,第一天能打那么多道题(19 ...
- Kafka设计解析(四)- Kafka Consumer设计解析
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...
- TP5与TP3.X对比
首先声明本章节并非是指导升级旧的项目到5.0,而是为了使用3.X版本的开发者更快的熟悉并上手这个全新的版本.同时也强烈建议开发者抛弃之前旧的思维模式,因为5.0是一个全新的颠覆重构版本. 需要摒弃的3 ...
- 如何设置mysql远程访问及防火墙设置
笔者在一个实际的项目中需要MYSQL远程访问. 情景: 安装好Mysql, 本地访问正常,很奇怪局域的机器都无法访问该服务器上的MYSQL数据库. 经过资料查找 原来Mysql默认是不可以通过远程机器 ...