Nagle算法
如果有过多的小分组在网络中进行传输, 这会降低网络的利用率. 假如每个分组都只有一个字节数据组成的TCP数据报的话, 也就是糊涂窗口综合症, 这时可想而知整个网络的利用率有多低. 而采用Nagle
算法能明显减少上述可能出现的情况, 并提高网络带宽, 减缓网络拥塞.
Nagle
的规则 :
-
如果包长度达到MSS,则允许发送;
-
如果该包含有FIN,则允许发送;
-
设置了TCP_NODELAY选项(网络编程
setsockopt
函数中设置, 默认开启),则允许发送; -
未设置TCP_CORK选项时(网络编程
setsockopt
函数中设置),若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送; -
上述条件都未满足,但发生了超时(一般为200ms),则立即发送.
Nalge
算法有一个很重要的要求 : 一个TCP连接上最多只能有一个未被确认的未完成的小分组, 在该分组的确认到达之前不能发送其他的小分组. 所以当第一次发送时有数据就立马发送, 当对端的ACK
没有到来之前或者超时之前都不能在发送分组, 将没有发送的小分组全部缓存下来组成一个大的分组等到满足条件之后再发送. 但是该算法也有一个缺点, 就是迟延的确认有可能迫使发送端重传其未被确认的报文段.
Nagle
算法完整代码在 : Nagle.c
服务端输入 :
./a.out 1 8080 192.168.1.16
客服端输入 :
./a.out 2 8080 192.168.1.16
代码中设置的是客服端连接时就向服务端发送1000个字节, 但是每次只发送一个字节. 如果开启Nagle
算法, 客服端必须每次都要等待对端的ACK
到来才发下一个分组, 结果如图视 :
关闭Nagle
算法就将99行的代码注释取消掉再来运行. 既然关闭了Nagle
算法, 那么不需要等待对端的ACK
到来才分组, 只要有分组就立马发送, 结果如图视 :
CORK算法
CORK
算法较Nagle
算法则更为激进, 一旦打开CORK
算法(网络编程setsockopt
函数中设置TCP_CORK选项), TCP不关注是否有收到ACK报文, 只要当前缓存中累积的数据量不足以组成一个MTU大小的数据包就不会将数据包发出, 直到一个RTO超时后才会把不满足一个MTU大小的数据包发出去.
CORK
算法暂时没有实验成功, 所以也暂时没有实例来分析. 可以在套接字选项中设置TCP_CORK
来验证.
总结
Nagle
算法主要关心网络拥塞问题, 而CORK
算法是为了提高网络的利用率. 但是两者都是为了尽量避免糊涂窗口综合症的问题.
- 理解
Nagle
算法 - 理解
CORK
算法在哪里与Nagle
算法不同.