TCP(一)四次握手关闭一个TCP连接?

一直以来的一个观点就是TCP通过4次握手即可关闭一个连接。但今天经过多次抓包测试,我发现真实的情形往往比教科书所写的4次握手机制更复杂。

测试的结论为有三种不同的关闭机制,分别为:4次握手关闭,3次握手关闭和异常关闭(通过发送RST包关闭TCP连接)

本着 实践出真理!要有图有真相!的方法论我做了如下测试以及相应的记录!

本次的实验工具为chrome浏览器,实验方法是在地址栏上输入一个图片的URL并回车,并通过wireshark来抓包。
在我的测试样本中,划分为3种不同的情形,如下所述


1. 图片请求完后不关闭浏览器

这种情况确实是最常见的
当服务器在发送完一个http响应包之后,若等待一分钟内(测试大约为60秒)监测到这个插口对上没有新的http请求包,则会主动来关闭连接(发送FIN包),客户端在收到FIN包后会做出响应(发送ACK包),这个步骤是没有问题的,问题是对于之后的步骤测试中出现了3种情况!

1.1 客户端自动发送FIN包,服务器收到后返回ACK包确认
TCP(一)四次握手关闭一个TCP连接?_第1张图片

这个是教科书版本的四次握手关闭

1.2 客户端自动发送FIN包,但是服务器直接舍弃并发送RST包

在发送完ACK包之后,客户端会自动去发送FIN包,但是服务器直接舍弃了这个FIN包,并发送一个RST包来异常关闭这个连接!

1.3 客户端发送2次检测包后,服务器发送RST包

TCP(一)四次握手关闭一个TCP连接?_第2张图片

实验测试表示:客户端会发送2次检测包以维持TCP连接,服务端 在发完FIN包之后累计收到2次检测包后便会发送RST包来中断连接。

【概括来说,第一种是正常关闭,第二和第三中情形均为异常关闭(目前仍不清楚由哪些原因导致)】

2. 图片请求完后立即关闭浏览器

通过测试可以发现,当关闭浏览器后,所有通过该浏览器建立的TCP连接会发送FIN包来表示关闭连接

TCP(一)四次握手关闭一个TCP连接?_第3张图片

握手关闭的三个TCP包都罗列在红框内:
有两个发现:

  1. 在一分钟内的等待期内,若客户端主动来发送FIN包后,服务器一收到客户端发来的FIN包,便提前发送FIN包来响应(而不是等到等待期结束后再发送)
  2. 客户端主动关闭的情况下,两端仅通过了三次握手即关闭了连接(服务器将ACK包与自己要发送的FIN包组合在了一起一并发送了【标准关闭机制中的第二步和第三步合在了一起】)

3. 图片请求完后等收到服务器端发送的FIN包后,再关闭浏览器

TCP(一)四次握手关闭一个TCP连接?_第4张图片

在收到服务器端发送的FIN包并发送完ACK包之后,我把浏览器关闭了,此时也便得到了教科书版本的四次握手关闭!


最后还是有必要来总结一下的:
这次的测试过程不仅发现了TCP灵活多变的握手关闭机制
还是有些额外的收获

  1. 浏览器HTTP请求的过程,大多都是服务器主动去关闭连接(除非是http请求完的1分钟内关闭浏览器,但这是不常见的情形),所以服务器会有大量的TIME_WAIT状态的TCP连接,这种情况下必须要缩短TIME_WAIT的时间,不能使用默认的4分钟(2msl),否则当积累太多的TIME_WAIT状态的TCP连接后,服务很容易挂掉!
  2. 客户端对服务器同一个插口(例如:106.14.17.171:80)的间隔一分钟内多次http请求,浏览器会复用为现有的TCP连接并基于此进行多次http请求,而不是客户端为每一次http请求单独占用一个新的插口。
  3. 第一次尝试用Markdown写日志,写作如行云流水,特别舒畅!为Markdown疯狂打call!

你可能感兴趣的:(TCP(一)四次握手关闭一个TCP连接?)