上文介绍了TCP可靠传输的基本情况,但其实忽略了个问题——传递给应用层处理也是需要时间的,这一节介绍这个处理时间会带来什么以及TCP的解决方案
什么是流控制(flow control)
应用层从传输层socket中提取数据,然而往往数据不会提的这么快,这时候要是sender还一直发数据就会挤满接收端的缓存(RcvBuffer),挤满后传输的数据就只能作废。
∴ 出现了流控制:receiver跨过整个告诉sender我缓存区里还可以存的数据大小(rwnd),要求sender只能发送小于rwnd大小的数据以防止上面的情况发生
需要注意
流控制与整个网络的堵塞情况无关,也不能直接影响网络堵塞情况
有关的两个关于传输数据大小的概念
MSS: Max segment size,最大段大小,在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(不包括文段头)。也就是data的总量
MTU: Max Transmission Unit,最大传输单元,发送方能够接受的有效载荷大小,反应出来也是网络层能够传输的最大大小。如果MTU过大,在碰到路由器时会被拒绝转发,因为它不能处理过大的包。
流控制遇到的其他问题
Nagle's algorithm
人类发送数据的速度相对于网络速度实在是太慢了,所以经常会出现输入一个就立刻传过去个包,而包里其实基本都是headers没什么data
Nagle's algorithm 就是解决这种情况的一个算法
- 收到第一个信息,直接发送
- 当出现 【发送端的字符总量大小凑到了MSS】 且 【接收端发来ACK说接到了上一个(TCP连接上最多只有一个未被确认的分组)】 的时候,发送剩下的包
体现在图中,就是HELLO被分成两部分,其中H被立刻发送,ELLO合成一个包发送,且并不连续
你可以在很多应用里找到这个算法,比如xshell
白痴窗口综合症
白痴窗口综合症 (Silly Window Syndrome)也是病症之一。
- app收的太慢了,接收端的缓存很快被填满,结果应用层还是每次就收一俩字节
- 接受端发给sender的命令也就每次都只能告诉发一两个
- 就出现了上面Nagle's algorithm提到的问题,传输的都是没什么信息的小包,还会让本就不充裕的信道效率雪上加霜
解决办法一般也很简单:等rwnd比较大了再通知sender就成!