前一段时间在使用Wireshark抓包的时候,闲着没事跟踪了一下TCP的stream,发现了一个神奇的现象,如下图:

图1

这是此次TCP连接关闭时的报文,不知道大家有没有发现什么怪怪的地方,没错,那就是报文发送的顺序。
大家一定很熟悉下面这张图:
图2

这张图被很多的网站和文章所引用,一般大家理解的TCP四次挥手就是这张图了,可是如果按照上图中的流程来的话(为了方便我们将192.168.0.108称为a,将36.110.213.227称为b):

  1. 首先a向b发送FIN报文请求关闭连接,a的FIN报文的Sequence number为627。
  2. 此时b收到a的FIN报文应该对a回复一个确认的ACK报文,自己的Sequence number为219,确认的Acknowledgement number应该为a的FIN报文Sequence number +
    1即627 + 1 = 628(因为SYN/FIN报文虽然不携带数据但是还是要占用1个字节的序列号)。
  3. b待到自己对a的传输结束后向a发送FIN报文,自己的Sequence number为219(ACK报文可以携带数据,但是不携带数据时不占用序列号所以还是219),确认的Acknowledgement
    number为627 + 1 = 628。
  4. a收到b的FIN报文回复一个ACK确认报文,自己的Sequence number为627 + 1 = 628,确认的Acknowledgement
    number为219 + 1 = 220。

这个结果与我们抓包的结果并不相同,首先在第二步,b并没有发送回复a FIN的ACK报文,而是直接发送了自己的FIN报文,而且我们可以注意到b FIN报文的对a要求的Acknowledgement number是627,但是之前a发送FIN报文时已经使用了627.
这都跟我之前认知中的TCP四次挥手步骤对不上,为什么会这样?

我翻阅了经典著作《TCP/IP详解卷一:协议》,才发现经常被引用的图二只是TCP关闭时一种情况,TCP连接关闭还存在双方同时关闭的情况,如图3所示:
图3

是的,这种情况完全符合我抓包的结果,这种情况是通信的双方都都扮演着客户端与服务端的角色出现的。原来我之前的认知只是片面的,看来学知识还是要去阅读一些经典之作以免造成以偏概全的现象(小声逼逼:网上有些文章抄都抄不全这不是坑人嘛 )。

Last modification:January 17th, 2020 at 05:14 am
大家一起分享知识,分享快乐