这次再写一些协议簇中TCP的相关东西,TCP作为常用的协议之一,能说的东西太多了,连HTTP都是在TCP的基础上封装的。这次说的是TCP中的流量控制相关的知识。
先上一些概念:
MTU:Maximum Transmit Unit : 最大传输单元,即物理接口(数据链路层)提供给上层的(通常是IP层)最大一次传输数据的大小,以普通使用的以太网接口为例,缺省MTU=1500Byte (缺省的意思就是默认的),这是以太网接口对IP层的约束,如果IP层有<=1500Byte需要发送,只需要一个IP包就可以完成发送任务,自然,当大于1500字节时,需要分片发送,如何判断两个分片是一个包?这两个分片的IP Header ID 相同。

MSS:Maximum Segment Size :TCP提交给IP层最大分段大小,不包含TCP Header和TCP Option。只包含TCP Payload,MSS是TCP用来限制application层最大的发送字节数,如果底层物理接口MTU=1500Byte,那么MSS就等于MSS=1500-20(IP header)-20(TCP header)=1460字节
如果应用层有2000字节需要发送,则需要分包,第一个segment包等于1460字节,第二个segment包等于540字节。

有了这两个概念,我们心中可以建立这样一个初步的认知:
TCP通信的双方,都有自己的单次最多能够发送的数据量。
假如此时A和B通信,那么A单次能发送给B的最大数据量是多少呢?
这取决于两个值,一个是本地物理接口能发送的最大数据量,这个很好理解,因为不管软件再优化,也是无法突破物理限制的。
第二个值是B的MSS值。
通信双方的最终MSS=双方较小的MTU-40
这里的40等于TCP头和IP头


先回忆一下第一篇文章的关于初始序列号ISN的概念:

A和B告知彼此的第一个发送字节的初始序列号,建立连接后对每一个发送的字节都需要以初始序列号为原点进行编号,需要对方来确认每一个字节编号都已经成功接收,双方初始序列号是由OS(Operate System,操作系统)动态生成的,随机的值,一般每个TCP
session都会有不一样的初始序列号,占四个字节。


接下来说另一个非常重要的流量控制方法:滑动窗口
我们来模拟一个发送数据的过程:
为了便于描述,假定A和B的初始序列号都为0,A发1024字节的数据给B,B通告给A的window size = 4096。对于A来说,最初的slide window 左侧是自己的原点,即初始序列号0,右侧就是 A的初始序列号+ B通告给A的 window size= 4096;
IF:
A发出的1024 byte 数据如果没有得到B确认,A的slide window依然是静止的。
Else IF:
A发出的1024 byte 数据如果得到B确认,B通告的 window = 3072,说明数据还在TCP接收缓冲区,application没有取走,则A的slide window左侧向右的方向移动1024,右侧依然静止是4096 ( 1024 + 3072)。
Else IF:
A发出的1024 byte 数据如果得到B确认,B通告的 window = 4096,说明数据被application取走,则A的slide window左侧向右的方向移动1024,右侧移动到5120 ( 1024 + 4096)。

总结一下,A的slide window 左侧是自己发出,并被对方确认的字节序列号,右侧是左侧+ B通告window size。

那么这个window size 是怎么来的呢?
如果A发送给B window size = 8192,意思是:B最多可以连续发送8192 byte 给A —— 在A ACK这8192 byte之前。

那A的这个8192byte 怎么来的呢? 一般来说,8192byte就是A的接收缓区,A_Receive_Buffer= 8192,如果B不小心发送超过8192 byte,如果application没有及时取走,则超过8192 byte 数据可能会因为A_Receive_Buffer满而被丢弃,所以B会严格遵守A的 advertised window size,如果A通告的window = 0,则B一定不会发送数据。Window Size 占两个byte,最大值为65535,它对对方发送速率影响很大。如果window size 是高速网络带宽的瓶颈,可以采用TCP Option scaling window 这个选项。

Last modification:May 23rd, 2019 at 09:44 pm
如果觉得我的文章对你有用,请随意赞赏