我们都知道 TCP
的连接和关闭过程,简称为三次握手和四次挥手。
这次我们使用 wireshark
这个抓包工具从报文段( 分组 )的角度进一步了解其报文传输过程,对所谓的三次握手和四次挥手有一个感性的认识。
1.简述三次握手过程
1). 主动开启者(通常称为客户端)发送一个 SYN
报文段(即一个在 TCP
头部的SYN
位字段置位的 TCP/IP
数据包),并指明自己想要连接的端口号和它的客户端初始序列号(记为IsN(c)
)。通常,客户端还会借此发送一个或多个选项。客户端发送的这个 SYN
报文段称作段1;
2).服务器也发送自已的 SYN
报文段作为响应,并包含了它的初始序列号(记作 ISN(s)
)。该段称作段2。此外,为了确认客户端的 SYN
,服务器将其包含的 ISN(C)
数值加1后作为返回的 ACK
数值。因此,每发送一个 SYN
,序列号就会自动加1。这样如果出现丢失的情况,该 SYN
段将会重传;
3).为了确认服务器的 SYN
,客户端将 ISN(S)
的数值加1后作为返回的 ACK
数值。这称作段3。
2.使用 wireshark 进行抓包
我们尝试登录 Web
服务器进行 TCP
连接,并且立刻退出:
# telnet 123.57.134.153 80
...
...
# quit
wireshark
抓包的结果如下所示:
我们可以看到三次握手的过程中即为三次报文发送过程:[SYN]
、[SYN ACK]
和 [ACK]
我们来看客户端向服务器发送的 SYN
请求报文段内容:
[SYN]
报文段的初始序列号 Seq
为 0, 但是下方的详细报文内容中可以看到 Sequence number: 0 (relative sequence number)
这个字段描述,这说明该序列号 IsN(c)
只是相对序列号,因为没有任何报文段发出,所以是0。还可以看到 Sequence number (raw): 852679803
的字段,这说明初始序列号是 852679803
,本质上并不是 0。(其实这个初始序列号是采用半随机的方法产生的,具体的产生方法本人也不是很清楚,需要查看 RFC
白皮书)
然后是服务器发来的 [SYN ACK]
报文段:
该报文段是服务器发送自己的连接请求 SYN
, 并且对客户端发来的 [SYN]
报文段进行确认,即确认字段置位,并且确认号为 IsN(c) + 1
,即相对的确认号为 1,但是绝对的确认号就是上面的 852679803
加1。也就是在详细报文内容中的两个字段:Acknowledgment number: 1 (relative ack number)
和 Acknowledgment number (raw): 852679804
。并且服务端有自己的初始序列号INC(S)
, 相对序列号为 0
, 绝对序列号为 852679804
。
三次握手的最后一个报文段是客户端对服务端发来的 [SYN+ACK]
进行的确认报文段 [ACK]
:
其中最重要的字段就是确认号,其值服务器发来的 [SYN ACK]
的报文段的序列号加一,也就是详细报文内容中的: Acknowledgment number: 1 (relative ack number)
和 Acknowledgment number (raw): 1797564312
。
这样,经过三次报文交换,连接就建立了。
3.简述四次挥手过程
还是这张示意图:
1.连接的主动关闭者发送一个 FIN
段指明接收者希望看到的自已当前的序列号 Seq
。 FIN
段还包含了一个 ACK
段用于确认对方最近一次发来的数据。
2.连接的被动关闭者将 Seq
的数值加1作为响应的 ACK
值,以表明它已经成功接收到
主动关闭者发送的 FIN
。此时,上层的应用程序会被告知连接的另一端已经提出了关闭的请求。通常,这将导致应用程序发起自已的关闭操作。接着,被动关闭者将身份转变为主动关
闭者,并发送自已的 FIN
。
3.为了完成连接的关闭,最后发送的报文段还包含一个 ACk
用于确认上一个 FIN
。值
得注意的是,如果出现 FIN
丢失的情况,那么发送方将重新传输直到接收到一个 ACK
确认为止。
4.使用 wireshark 进行抓包分析四次挥手
1.首先主动关闭者(这里的例子是服务器主动关闭)会发送一个 [FIN ACK]
报文:
其中 FIN
字段用于表示请求释放连接,还包含对上次的报文的确认号 ACK
。
2.被动关闭者(客户端)对主动关闭者发来的 [FIN]
报文段进行确认,确认号是主动关闭者的Seq
的数值加1:
3.被动关闭者(客户端)发起自己的关闭操作,接着,被动关闭者(客户端)将身份转变为主动关闭者,并发送自已的 [FIN]
:
4.最后,主动关闭者还要对被动关闭者(客户端)发来的自己的 [FIN]
进行确认,确认号为上个报文段的序列号 Seq
加1:
综上所述,建立一个TCP连接需要3个报文段,而关闭一个TCP连接需要4个报文段。并且我们使用 wireshark
对每个报文段进行了分析,希望大家对这个看不见的报文交换已经有一个感性的认识了。
2020/7/12 成都