图解 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 条回复
est
2017-07-12 14:17:51 +08:00
LZ 放心。在公众号写技术文章没人看的。
introom
2017-07-12 14:44:48 +08:00
@est 写鸡汤?
SKull4
2017-07-12 14:58:21 +08:00
每次握手,回首出现了问题会怎样
zealot0630
2017-07-12 16:56:32 +08:00
"为什么要进行三次握手" 这个问题回答到并不好 我只能给 4/10 分
zealot0630
2017-07-12 16:58:33 +08:00
三次握手其中一个功能是防 DDOS,先领会到这里能拿及格分
ibufu
2017-07-12 17:02:13 +08:00
还以为是来讲笑话的
enocher
2017-07-12 17:07:28 +08:00
@SKull4 以第三次客户端没有发送给服务器 ack 请求为例子,这里涉及到超时和重传机制,这个时候服务器没法进入 ESTABLISHED 状态,如果超过一定时间服务器后向客户端发送 RTS 报文,同时进入 CLOSED 状态。深入一点也可以去了解一下 syn 攻击之类的 :)
ajan
2017-07-12 17:18:04 +08:00
完全没有在微信里看文章的癖好~
Geoion
2017-07-12 17:20:13 +08:00
没人会在公众号看技术文章的,据我观察在朋友圈转发技术文章的,都是没有女朋友的。
araraloren
2017-07-12 17:24:45 +08:00
MARK

@est 还行,只要文章好还是有人看的,我就关注了 CloudMan,写的关于云和容器的东西还不错,每天 5 分钟。。
Chingim
2017-07-12 17:37:27 +08:00
@zealot0630 如何防 ddos,期待展开
woshixiaohao1982
2017-07-12 17:42:18 +08:00
@zealot0630 #5 ddos 实际上 根本防不了,链路层上 就打垮你了
panda1001
2017-07-12 17:49:56 +08:00
@zealot0630
@enocher 指出的 syn 攻击就是利用三次握手机制 不知到是怎么防止 ddos ?
andyL
2017-07-12 18:01:03 +08:00
Mark
andyL
2017-07-12 18:02:12 +08:00
不该 mark 的,直接收藏了。

期待前排大佬能把争论的地方讲具体、讲清晰一点
anxious
2017-07-12 18:07:21 +08:00
建立连接三次握手,常见的有一个 SYN 攻击。

在三次握手的过程中,server 端会维护一个队列,这个队列中都是 已经向 client 返回 ACK,并等待 client ACK 的请求。

如果 client 在此时恶意的不发送 ACK,而是不停的发送 SYN,
就会导致 SERVER 端 的队列被占满,无法接受正常的 TCP 三次握手请求。
qien
2017-07-12 18:22:10 +08:00
TIME_WAIT 状态是怎样产生的,为什么要这样做?
xx998
2017-07-12 18:28:28 +08:00
@anxious 多谢科普
ivechan
2017-07-12 18:37:17 +08:00
为什么要把教科书搬到微信公众号上。。
enocher
2017-07-12 18:51:46 +08:00
@qien The client waits for a period of time equal to double the maximum segment life (MSL) time, <b>to ensure the ACK it sent was received.</b>

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

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

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

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

© 2021 V2EX