tcp/ip 只有四次揮手?還有三次揮手

在這裏插入圖片描述
我們經常說tcp/ip 三次握手與四次揮手,實時上tcp/ip並不總是這樣,它會存在一些特殊情況,並對這些特殊情況作了優化,下面給大家演示一遍:

抓取我的服務器地址8080端口的一次http請求 ,在服務器端執行命令,抓取8080端口的請求:

tcpdump -S -i eth0   tcp port 8080
在客戶端請求url地址

wget  http://118.24.47.200:8080/jvm/getJVMList.json

抓取到的數據包如下:

00:05:30.076277 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [S], seq 3495051296, win 14600, options [mss 1424,sackOK,TS val 1695780977 ecr 0,nop,wscale 7], length 0
00:05:30.076294 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [S.], seq 485492531, ack 3495051297, win 28960, options [mss 1460,sackOK,TS val 629900081 ecr 1695780977,nop,wscale 7], length 0
00:05:30.115447 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492532, win 115, options [nop,nop,TS val 1695781016 ecr 629900081], length 0
00:05:30.115916 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [P.], seq 3495051297:3495051432, ack 485492532, win 115, options [nop,nop,TS val 1695781017 ecr 629900081], length 135
00:05:30.115924 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [.], ack 3495051432, win 235, options [nop,nop,TS val 629900120 ecr 1695781017], length 0
00:05:30.117071 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [P.], seq 485492532:485492629, ack 3495051432, win 235, options [nop,nop,TS val 629900122 ecr 1695781017], length 97
00:05:30.156220 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492629, win 115, options [nop,nop,TS val 1695781057 ecr 629900122], length 0
00:05:30.157325 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [F.], seq 3495051432, ack 485492629, win 115, options [nop,nop,TS val 1695781058 ecr 629900122], length 0
00:05:30.157562 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [F.], seq 485492629, ack 3495051433, win 235, options [nop,nop,TS val 629900162 ecr 1695781058], length 0
00:05:30.196710 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492630, win 115, options [nop,nop,TS val 1695781097 ecr 629900162], length 0

解釋上面的通信過程

#三次握手第一步 客戶端發起連接請求    客戶端初始序列號爲 3495051296
#sin seq = 3495051296
00:05:30.076277 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [S], seq 3495051296, win 14600, options [mss 1424,sackOK,TS val 1695780977 ecr 0,nop,wscale 7], length 0
#三次握手第二步 服務端應答            服務器端初始序列號爲 485492531
#sin seq = 485492531 ack = 3495051296 +1 = 3495051297
00:05:30.076294 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [S.], seq 485492531, ack 3495051297, win 28960, options [mss 1460,sackOK,TS val 629900081 ecr 1695780977,nop,wscale 7], length 0
#三次握手第三步 客戶端應答           客戶端序列號爲 3495051297
#ack ack = 485492532 + 1
00:05:30.115447 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492532, win 115, options [nop,nop,TS val 1695781016 ecr 629900081], length 0
#客戶端向服務器發送數據包            客戶端序列號爲 3495051432
#push seq = 3495051297:3495051432  數據包長度 length = 3495051432 - 3495051297 = 135
00:05:30.115916 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [P.], seq 3495051297:3495051432, ack 485492532, win 115, options [nop,nop,TS val 1695781017 ecr 629900081], length 135
#服務器端接收數據包應答              服務器端序列號爲 485492532
#ack  = 3495051432
00:05:30.115924 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [.], ack 3495051432, win 235, options [nop,nop,TS val 629900120 ecr 1695781017], length 0
#服務器端返回響應內容數據包          服務器端序列號爲 485492629 
#push seq = 485492532:485492629  數據包長度 length = 485492629 - 485492532 = 135  ack = 3495051432
00:05:30.117071 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [P.], seq 485492532:485492629, ack 3495051432, win 235, options [nop,nop,TS val 629900122 ecr 1695781017], length 97
#客戶端接收數據包應答                客戶端序列號爲 3495051432
#ack = 485492629代表收到的包的序列號;
00:05:30.156220 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492629, win 115, options [nop,nop,TS val 1695781057 ecr 629900122], length 0
#三次揮手 -- 客戶端發起斷開連接請求    客戶端序列號爲 3495051432
#fin  seq = 3495051432
00:05:30.157325 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [F.], seq 3495051432, ack 485492629, win 115, options [nop,nop,TS val 1695781058 ecr 629900122], length 0
#三次揮手 -- 服務器端發起斷開連接請求
#ack = 3495051432 + 1 = 3495051433  注意 因爲服務器端也沒有東西要發送了,所以也要關閉連接,因此同時發送了fin信號,seq = 485492629
00:05:30.157562 IP VM_0_6_centos.webcache > 221.122.42.100.58706: Flags [F.], seq 485492629, ack 3495051433, win 235, options [nop,nop,TS val 629900162 ecr 1695781058], length 0
#三次揮手 -- 客戶端應答
#ack = 485492629 + 1 = 485492630 
00:05:30.196710 IP 221.122.42.100.58706 > VM_0_6_centos.webcache: Flags [.], ack 485492630, win 115, options [nop,nop,TS val 1695781097 ecr 629900162], length 0

看到這裏有沒有發現最後的揮手狀態,並不是四次揮手,而是三次揮手???

這是因爲關閉連接有兩種方式,當一方關閉連接,另外一方沒有數據發送時,馬上關閉連接,也就將第二步的ack與第三步的fin合併爲一步了,這個優化在RFC793 3.5節:

3.5. Closing a Connection
CLOSE is an operation meaning “I have no more data to send.” The notion of closing a full-duplex connection is subject to ambiguous interpretation, of course, since it may not be obvious how to treat the receiving side of the connection. We have chosen to treat CLOSE in a simplex fashion. The user who CLOSEs may continue to RECEIVE until he is told that the other side has CLOSED also. Thus, a program could initiate several SENDs followed by a CLOSE, and then continue to RECEIVE until signaled that a RECEIVE failed because the other side has CLOSED. We assume that the TCP will signal a user, even if no RECEIVEs are outstanding, that the other side has closed, so the user can terminate his side gracefully. A TCP will reliably deliver all buffers SENT before the connection was CLOSED so a user who expects no data in return need only wait to hear the connection was CLOSED successfully to know that all his data was received at the destination TCP. Users must keep reading connections they close for sending until the TCP says no more data. [Page 37]

                                                      September 1981

Transmission Control Protocol
Functional Specification

There are essentially three cases:

1) The user initiates by telling the TCP to CLOSE the connection

2) The remote TCP initiates by sending a FIN control signal

3) Both users CLOSE simultaneously

Case 1: Local user initiates the close

In this case, a FIN segment can be constructed and placed on the
outgoing segment queue.  No further SENDs from the user will be
accepted by the TCP, and it enters the FIN-WAIT-1 state.  RECEIVEs
are allowed in this state.  All segments preceding and including FIN
will be retransmitted until acknowledged.  When the other TCP has
both acknowledged the FIN and sent a FIN of its own, the first TCP
can ACK this FIN.  Note that a TCP receiving a FIN will ACK but not
send its own FIN until its user has CLOSED the connection also.

Case 2: TCP receives a FIN from the network

If an unsolicited FIN arrives from the network, the receiving TCP
can ACK it and tell the user that the connection is closing.  The
user will respond with a CLOSE, upon which the TCP can send a FIN to
the other TCP after sending any remaining data.  The TCP then waits
until its own FIN is acknowledged whereupon it deletes the
connection.  If an ACK is not forthcoming, after the user timeout
the connection is aborted and the user is told.

Case 3: both users close simultaneously

A simultaneous CLOSE by users at both ends of a connection causes
FIN segments to be exchanged.  When all segments preceding the FINs
have been processed and acknowledged, each TCP can ACK the FIN it
has received.  Both will, upon receiving these ACKs, delete the
connection.

[Page 38]

September 1981
Transmission Control Protocol
Functional Specification

  TCP A                                                TCP B
  1. ESTABLISHED ESTABLISHED

  2. (Close)
    FIN-WAIT-1 --> <SEQ=100><ACK=300><CTL=FIN,ACK> --> CLOSE-WAIT

  3. FIN-WAIT-2 <-- <SEQ=300><ACK=101><CTL=ACK> <-- CLOSE-WAIT

  4.                                                   (Close)
    

    TIME-WAIT <-- <SEQ=300><ACK=101><CTL=FIN,ACK> <-- LAST-ACK

  5. TIME-WAIT --> <SEQ=101><ACK=301><CTL=ACK> --> CLOSED

  6. (2 MSL)
    CLOSED

                   Normal Close Sequence
    
                         Figure 13.
    

    TCP A TCP B

  7. ESTABLISHED ESTABLISHED

  8. (Close) (Close)
    FIN-WAIT-1 --> <SEQ=100><ACK=300><CTL=FIN,ACK> … FIN-WAIT-1
    <-- <SEQ=300><ACK=100><CTL=FIN,ACK> <–
    … <SEQ=100><ACK=300><CTL=FIN,ACK> -->

  9. CLOSING --> <SEQ=101><ACK=301><CTL=ACK> … CLOSING
    <-- <SEQ=301><ACK=101><CTL=ACK> <–
    … <SEQ=101><ACK=301><CTL=ACK> -->

  10. TIME-WAIT TIME-WAIT
    (2 MSL) (2 MSL)
    CLOSED CLOSED

                Simultaneous Close Sequence
    

————————————————
版權聲明:本文爲CSDN博主「朱清震」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zqz_zqz/article/details/79548381

發佈了158 篇原創文章 · 獲贊 72 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章