图解 TCP 三次握手与四次挥手

2017-07-12 14:13:56 +08:00
 enocher

引言

TCP 三次握手和四次挥手不管是在开发还是面试中都是一个非常重要的知识点,它是我们优化 web 程序性能的基础。但是大部分教材都对这部分解释的比较抽象,本文我们就利用 wireshark 来抓包以真正体会整个流程的细节。

三次握手

根据下面这幅图我们来看一下 TCP 三次握手。p.s: 每个箭头代表一次握手。

第一次握手

client 发送一个SYN(J)包给 server,然后等待 server 的 ACK 回复,进入SYN-SENT状态。p.s: SYN 为 synchronize 的缩写,ACK 为 acknowledgment 的缩写。

第二次握手

server 接收到 SYN(seq=J)包后就返回一个ACK(J+1)包以及一个自己的**SYN(K)**包,然后等待 client 的 ACK 回复,server 进入SYN-RECIVED状态。

第三次握手

client 接收到 server 发回的 ACK(J+1)包后,进入ESTABLISHED状态。然后根据 server 发来的 SYN(K)包,返回给等待中的 server 一个ACK(K+1)包。等待中的 server 收到 ACK 回复,也把自己的状态设置为ESTABLISHED。到此 TCP 三次握手完成,client 与 server 可以正常进行通信了。

为什么要进行三次握手

我们来看一下为什么需要进行三次握手,两次握手难道不行么?这里我们用一个生活中的具体例子来解释就很好理解了。我们可以将三次握手中的客户端和服务器之间的握手过程比喻成 A 和 B 通信的过程:

wireshark

上面分析还不够形象,很容易忘记,下面我们利用 wireshark 来证明一下上面的分析过程。从下面的的输出就可以很容易看出来,必须要经过前面的三次 tcp 请求才会有起一次 http 请求。

第一次请求客户端发送一个 SYN 包,序列号是 0。

第二次请求服务器会发送一个 SYN 和一个 ACK 包,序列号是 0,ack 号是 1。

第三次本地客户端请求会发送一个 ACK 包,序列号是 1,ack 号是 1 来回复服务器。

四次挥手

以下面这张图为例,我们来分析一下 TCP 四次挥手的过程。

第一次挥手

client 发送一个FIN(M)包,此时 client 进入FIN-WAIT-1状态,这表明 client 已经没有数据要发送了。

第二次挥手

server 收到了 client 发来的 FIN(M)包后,向 client 发回一个ACK(M+1)包,此时 server 进入CLOSE-WAIT状态,client 进入FIN-WAIT-2状态。

第三次挥手

server 向 client 发送FIN(N)包,请求关闭连接,同时 server 进入LAST-ACK状态。

第四次挥手

client 收到 server 发送的 FIN(N)包,进入TIME-WAIT状态。向 server 发送**ACK(N+1)**包,server 收到 client 的 ACK(N+1)包以后,进入CLOSE状态; client 等待一段时间还没有得到回复后判断 server 已正式关闭,进入CLOSE状态。

References

TCP-CONNECTION TCP-TERMINATION

公众号

欢迎大家关注我的公众号ziwenxie_mj订阅我博客上的原创文章 :)

p.s: 如有错误,还望指正 :)

7151 次点击
所在节点    Linux
44 条回复
jtsai
2017-07-12 18:57:37 +08:00
那什么是 tcp 流
hsmocc
2017-07-12 19:14:36 +08:00
感觉在握手时候应该强调下序列号同步的功能
tempdban
2017-07-12 19:37:39 +08:00
看了评论舒了一口气
另外楼主这算是翻车么
cxbig
2017-07-12 20:04:36 +08:00
老实说,这些贴图质量实在是太土了。下面的 Wireshark 的部分跟本就看不清。
做推广能不能有点诚意。
JiPhone
2017-07-12 20:35:48 +08:00
补充一个[wireshark 网络分析]( https://book.douban.com/subject/26268767/),考虑到了 tcp 四次挥手中的 sack 导致的 seq 不一致问题
paradoxs
2017-07-12 20:37:33 +08:00
好 我来提个问
paradoxs
2017-07-12 20:37:58 +08:00
不小心发出去了。 接上面
HTTP 协议的无状态和 keep alive 的关系是什么
ljy2010a
2017-07-12 20:45:10 +08:00
把时序图 和各个状态放出来吧
netfee
2017-07-12 21:24:44 +08:00
恩,看着关注了一大堆公众号,不过基本上不会去看。为什么对封闭的微信热情这么高,开放的 Web 不是更好!?感谢楼主科普
ixinshang
2017-07-12 21:34:08 +08:00
值得看 谢谢
facetest
2017-07-12 21:37:48 +08:00
@zealot0630 建议多看书。
zoffy
2017-07-12 22:03:44 +08:00
作为一个 web 开发,平时都是用 http 协议,到底什么情况才需要深入到 tcp/ip 啊??
CRVV
2017-07-12 22:18:29 +08:00
"TCP 三次握手和四次挥手不管是在开发还是面试中都是一个非常重要的知识点,它是我们优化 web 程序性能的基础"
求问如何使用这些知识来优化 web 程序?
CRVV
2017-07-12 22:26:58 +08:00
三次握手的作用、带来的问题、问题的解决方案、解决方案仍然存在的问题,全部都在
https://tools.ietf.org/html/rfc7413 里面,讲得很清楚。而且 7413 比 793 短得多,很容易读完
Antidictator
2017-07-13 08:09:35 +08:00
@Geoion 我老师经常转,孩子都几个他
realfreesky
2017-07-13 08:53:57 +08:00
@qien 因为网络的不可靠性,在客户端发送了 ack 包之后,还需要等待 2ms 才到 closed 状态,因为 ack 包可能丢失,对方会重传 FIN 包,这时候客户端需要重传
Mutoo
2017-07-13 10:43:00 +08:00
@zealot0630 三次握手给 DDoS 提供了机会,并不是用来防 DDoS 的。
tony1016
2017-07-13 10:56:06 +08:00
还是喜欢这个版本:

你瞅啥
瞅你咋滴
呦,咋俩唠唠
suixinqiejing
2017-07-13 17:36:05 +08:00
萌新 请教。

在第二次通信中,B 向 A 发送信息之后,A 可以确认自己的发信能力和 B 的收信能力没有问题,但是 B 不知道自己的发信能力到底如何,所以就需要第三次通信。

B 向 A 发信息 为什么是确认 A 的发信能力。
suixinqiejing
2017-07-13 17:56:38 +08:00
上一个问题问的犹如智障 ,请无视。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/374778

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX