延时确认与nagle算法

来源:互联网 发布:运通汽车java 编辑:程序博客网 时间:2024/06/06 00:55

http://blog.chinaunix.net/uid-28387257-id-3766565.html

https://baike.baidu.com/item/Nagle%E7%AE%97%E6%B3%95/5645172?fr=aladdin


Nagle实在发送端实现的

Nagle算法的规则(可参考tcp_output.c文件里tcp_nagle_check函数注释):

(1)如果包长度达到MSS,则允许发送;
(2)如果该包含有FIN,则允许发送;
(3)设置了TCP_NODELAY选项,则允许发送;
(4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
(5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送。
举个例子,client端调用socket的write操作将一个int型数据(称为A块)写入到网络中,由于此时连接是空闲的(也就是说还没有未被确认的小段),因此这个int型数据会被马上发送到server端,接着,client端又调用write操作写入‘\r\n’(简称B块),这个时候,A块的ACK没有返回,所以可以认为已经存在了一个未被确认的小段,所以B块没有立即被发送,一直等待A块的ACK收到(大概40ms之后),B块才被发送。
另外可以通过设置TCP_QUICKACK选项来取消确认延迟,也就是不需要等待确认直接发送

使用TCP套接字选项TCP_NODELAY可以关闭套接字选项;

如下场景考虑关闭Nagle算法:

(1) 对端不向本端发送数据,并且对延时比较敏感的操作;这种操作没法捎带ack;

(2) 如上写-写-读操作;对于此种情况,优先使用其他方式,而不是关闭Nagle算法:

--使用writev,而不是两次调用write,单个writev调用会使tcp输出一次而不是两次,只产生一个tcp分节,这是首选方法;

--把两次写操作的数据复制到单个缓冲区,然后对缓冲区调用一次write;

--关闭Nagle算法,调用write两次;有损于网络,通常不考虑;



原创粉丝点击