源代码在这一篇文章里:
https://mp.csdn.net/editor/html/117086464
目录
6. 疑症 6 : TCP 的头号疼症 TIME_WAIT 状态
原文链接:
https://cloud.tencent.com/developer/article/1004327
说到TCP协议,相信大家都比较熟悉了,对于TCP协议总能说个一二三来,但是TCP协议又是一个非常复杂的协议,其中有不少细节点让人头疼点。本文就是来说说这些头疼点的,浅谈一些TCP的疑难杂症。那么从哪说起呢?当然是从三次握手和四次挥手说起啦,可能大家都知道TCP是三次交互完成连接的建立,四次交互来断开一个连接,那为什么是三次握手和四次挥手呢?反过来不行吗?
疑症 1 :TCP 的三次握手、四次挥手
下面两图大家再熟悉不过了,TCP的三次握手和四次挥手见下面左边的”TCP建立连接”、”TCP数据传送”、”TCP断开连接”时序图和右边的”TCP协议状态机”
TCP三次握手、四次挥手时序图
TCP协议状态机
要弄清TCP建立连接需要几次交互才行,我们需要弄清建立连接进行初始化的目标是什么。TCP进行握手初始化一个连接的目标是:分配资源、初始化序列号(通知peer对端我的初始序列号是多少),知道初始化连接的目标,那么要达成这个目标的过程就简单了,握手过程可以简化为下面的四次交互:
1 ) clien 端首先发送一个 SYN 包告诉 Server 端我的初始序列号是 X。
2 ) Server 端收到 SYN 包后回复给 client 一个 ACK 确认包,告诉 client 说我收到了。
3 ) 接着 Server 端也需要告诉 client 端自己的初始序列号,于是 Server 也发送一个 SYN 包告诉 client 我的初始序列号是Y。
4 ) Client 收到后,回复 Server 一个 ACK 确认包说我知道了。
整个过程4次交互即可完成初始化,但是,细心的同学会发现两个问题:
1. Server发送SYN包是作为发起连接的SYN包,还是作为响应发起者的SYN包呢?怎么区分?比较容易引起混淆
2.Server的ACK确认包和接下来的SYN包可以合成一个SYN ACK包一起发送的,没必要分别单独发送,这样省了一次交互同时也解决了问题1. 这样TCP建立一个连接,三次握手在进行最少次交互的情况下完成了Peer两端的资源分配和初始化序列号的交换。
大部分情况下建立连接需要三次握手,也不一定都是三次,有可能出现四次握手来建立连接的。如下图,当Peer两端同时发起SYN来建立连接的时候,就出现了四次握手来建立连接(对于有些TCP/IP的实现,可能不支持这种同时打开的情况)。