TCP流量控制-滑动窗口协议&Nagle算法

一.滑动窗口

服TCP全双工; A给B发送数据,则A有发送缓冲区; B有接收缓冲区。应用层的所有需要发送的数据都被放在了发送者的发送缓冲区。发送窗口是发送缓存中的一部分, 是可以被TCP协议发送的那部分。

发送缓冲区:

已发送并收到确认的数据、已发送但未收到确认的数据允许发送但尚未发送的数据,以及暂不允许发送的数据;

黄色部分组成了发送窗口(p1到p3)

 每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动(前提:前面的数据包收到确认之后),将新的数据包含到窗口中准备发送

二.流量控制

建立连接的时候,B会告诉A,自己的接收窗口大小(rwnd)。B每次给A回复确认数据包(ACK) ,也会告诉A自己的接收窗口大小。如果B告诉A自己的缓冲区己满(rwnd=0), A则停止发送数据。

(这里引入一个问题:A是知道什么时候在发送数据的呢,如果B接手窗口开放了,A也不会一直停止,总该在此发送呀)

这里就和上篇我们讲到的坚持定时器(持续定时器)相关了。大家可以回顾一下

就是通过这个16位的窗口大小告诉发送端接收端的窗口大小的

 

三.传输效率

单个发送字节单个确认,小包造成网络拥塞:

如果一个小包就要封装成报文段,加上TCP IP,和数据链路的报头。这样一个报文利用率就很低,再者同样大小的数据

分成若干个小报文段分成若干个大报文段,明显前者会浪费大量的网络资源。

针对上面的问题引出了Nagle算法

Nagle算法:尽可能次多 发送几个字节,避免网络因为太多的小包(协议头的比例非常之大)而拥塞。只允许个未被ACK的包存 在于网络(后面这个话的意思就是发送端发送一个数据包给接收端,在没有收到接收端的ACK之前,是不会发送下一个数据包的)

1.如果包长度达到MSS,则允许发送:

2.如果该包含有FIN,则允许发送(如果是终止报文段就直接发)

3.设置了TCP NODELAY选项, 则允许发送:禁止Nagile算法。(就不用延迟打包了)

4.Copk算法是Nagle算法的增强版,就是收到接收端确认后可以不用马上发送数据

未设置TCP CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送设置该选项后,内核会尽力把小数据包拼接成个大的数据包 (-个MTU) 再发送出去,当然若定时间后-般为200ms,该值尚待确认),内核仍然没有组合成一个MTU时 也必须发送现有的数据,CORK算法的目的是提高网络的利用率,使得总体上协议头占用的比例尽可能的小

int on = 1;

setsockopt(sockfd, SOL_TCP, TCP_COPK, &on, sizeof(on));

5.上述条件都未满足,但发生了超时(-一般为200ms)。则立即发送接收方等待段时间, 或者接收方获得足够的空间容纳一个报文段或者等到接收缓存有 半空闲的时候, 再通知发送方发送数据

 

更多的C/C++ linux编程我会在下面的文章中陆续的分享,也可以关注‘奇牛学院’

来一起讨论

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章