暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

深入理解TCP协议之滑动窗口

码农的修炼之道 2020-02-02
1032

    去年老张推荐了两本林沛满写的关于wireshark抓包的书,分别是《wireshark就是这么简单》和《wireshark分析的艺术》,写的真心不错。

      TCP协议是一个很有意思的内容,这半年对TCP协议有了更多的认识,于是想重新更新一些对TCP协议的内容。今天先从TCP协议里面的滑动窗口说起。


1、先说原理

         就发送端来说,一般如下所示:

        主要分为:已发送已确认的包(应用层未读取)。发送未确认的包,未发送可发送的包,未发送不可发送的包。

     其中,滑动窗口指的是发送未确认和未发送可发送区域的大小。


2、滑动窗口

     通常情况下,在wireshark抓包中看到的 win 表示向对方声明自己的接收窗口的大小,对方收到以后,会把自己的[发送窗口]限制在 指定大小之内。如果自己的处理能力有限,导致自己的接收缓冲区满,接收窗口大小为 0时发送端应该停止发送数据。


     比如,使用模拟工具产生的TCP报文,其中客户端窗口声明为20,抓包如下:

第1~3包:三次握手过程,其中第一包是客户端向服务端发起连接,并声明自己的接收窗口为20字节。第2包为服务端返回的ACK+SYN,同时也声明了自己的接收窗口29200字节。第三包为客户端回复服务端的ACK,此时自己接口窗口还是20。此后开始正常的数据收发。

第4包:服务器端向客户端发送的第一次数据,15个字节。

第5包:客户端回复服务器自己收到报文的ACK,同时确认号为16,此时窗口还是为20字节。

第6包:服务器端向客户端发送第二次数据,16个字节。

第7包:客户端回复服务器端自己收到的报文ACK=32,此时窗口还是为20字节。

第8包:服务器端发送14个字节,此时滑动窗口中可用窗口为6个字节。

第9包:服务器端向客户端发送6个字节,此时可用窗口为0,wireshark识别出来,自动显示为[TCP Window Full]

第10包:客户端确认了接收到的20个字节,可用窗口重现变为 20,因此重新声明自己的接收窗口win=20。


TCP Window Full

     再比如,客户端发起连接的时候声明自己的窗口为4000,其中MSS为1000。然后模拟服务端发送5000字节数据给客户端。


第1~3包:三次握手。其中第1包是客户端声明自己的接收窗口为4000,MSS为1000自己。第2包是服务端回复的ACK+SYN。第3包为客户端回复的ACK。

第4包:服务端发送1000字节数据给客户端,1000个字节正好为一个MSS。

第5包:服务器端发送1000字节数据给客户端。

第6包:服务器端发送1000字节数据给客户端。

第7包:服务器端发送1000字节数据给客户端。此时服务器端被wireshark解析处理[TCP window Full]代表此时客户端的接收窗口已经满了。

第8包~11包:服务端超时未收到客户端发来的确认ACK,服务端启动重传数据。


4 Zero Window

    出现零窗口的时候,服务端启动持续探测定时器,也叫Persist定时器。

    当接收端 B 接收窗口为 0 时,发送端 A 此时不能再发送数据,发送端此时开启 Persist 定时器,超时后发送一个特殊的报文给接收端看对方窗口否已经恢复,这个特殊的报文只有一个字节。


         比如某个wireshark的抓包结果如下:

第1~7包:包括了三次握手和正常通信数据包。

第8包:服务器端识别出客户端的接收窗口已经耗尽。

第9包:接收端回复的 ACK,携带了 win=0,wireshark 帮忙把这个包标记为了 TCP Zero window。

第10-25包:重传间隔是按照指数级退避,直到达到 120s 为止,一共重传尝试了16次(这个值由操作系统的参数决定),只是这里被wireshark标记为[TCP Keep-Alive]。


总结:

  • TCP Window Full 是站在发送端角度说的,表示此时发送端不能再发数据给对方,除非发送的数据包得到ACK。

  • TCP zero window 是站在接收端角度来说的,是接收端接收窗口满,自动告知对方不能再发送数据给自己。

文章转载自码农的修炼之道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论