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

猜你喜欢

转载自blog.csdn.net/zjcjava/article/details/103133607