网络协议10:【传输层】流控制以及对其中问题的解决

995 阅读2分钟

上文介绍了TCP可靠传输的基本情况,但其实忽略了个问题——传递给应用层处理也是需要时间的,这一节介绍这个处理时间会带来什么以及TCP的解决方案

什么是流控制(flow control)

image.png

应用层从传输层socket中提取数据,然而往往数据不会提的这么快,这时候要是sender还一直发数据就会挤满接收端的缓存(RcvBuffer),挤满后传输的数据就只能作废。

∴ 出现了流控制:receiver跨过整个告诉sender我缓存区里还可以存的数据大小(rwnd),要求sender只能发送小于rwnd大小的数据以防止上面的情况发生

需要注意

流控制与整个网络的堵塞情况无关,也不能直接影响网络堵塞情况

image.png

有关的两个关于传输数据大小的概念

MSS: Max segment size,最大段大小,在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(不包括文段头)。也就是data的总量
MTU: Max Transmission Unit,最大传输单元,发送方能够接受的有效载荷大小,反应出来也是网络层能够传输的最大大小。如果MTU过大,在碰到路由器时会被拒绝转发,因为它不能处理过大的包。

image.png

流控制遇到的其他问题

Nagle's algorithm

人类发送数据的速度相对于网络速度实在是太慢了,所以经常会出现输入一个就立刻传过去个包,而包里其实基本都是headers没什么data

Nagle's algorithm 就是解决这种情况的一个算法

  1. 收到第一个信息,直接发送
  2. 当出现 【发送端的字符总量大小凑到了MSS】【接收端发来ACK说接到了上一个(TCP连接上最多只有一个未被确认的分组)】 的时候,发送剩下的包

20160904160943950.png

体现在图中,就是HELLO被分成两部分,其中H被立刻发送,ELLO合成一个包发送,且并不连续

你可以在很多应用里找到这个算法,比如xshell

白痴窗口综合症

白痴窗口综合症 (Silly Window Syndrome)也是病症之一。

  • app收的太慢了,接收端的缓存很快被填满,结果应用层还是每次就收一俩字节
  • 接受端发给sender的命令也就每次都只能告诉发一两个
  • 就出现了上面Nagle's algorithm提到的问题,传输的都是没什么信息的小包,还会让本就不充裕的信道效率雪上加霜

解决办法一般也很简单:等rwnd比较大了再通知sender就成!