TCP_NODELAY

 
1 void Socket::setTcpNoDelay(bool on)
2 {
3   int optval = on ? 1 : 0;
4   ::setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY,
5                &optval, static_cast<socklen_t>(sizeof optval));
6   // FIXME CHECK
7 }
作者:车小胖
链接:https://www.zhihu.com/question/42308970/answer/246334766
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
关于宏TCP_NODELAY

30年前,阳澄湖的蟹农老王,每抓一只大闸蟹,就雇佣机器人开着卡车送到上海,然后再带着卖蟹的钱回来,老王想,这样好处是回款快(延迟小)。

但是,30年前的乡间小路,很快被一辆辆的卡车所堵塞,结果三天三夜也没有到达上海,老王的如意算盘泡汤了。

痛定思痛,老王觉得,没有必要一个螃蟹一辆车,可以将上午的所有螃蟹装在一辆卡车,上午发车;下午抓的螃蟹装在另一辆卡车里,下午发车。这样即使一天抓1000个螃蟹,也只需要两卡车,而不需要1000辆卡车

这样,乡间的小路也不会造成拥堵,上午发货,不一会儿,卖蟹的钱会被卡车运回来。

以上就是Nagle算法的通俗解释。

70-80年代,一些远程交互式软件,如Rlogin,客户端将用户输入的每一个字符独立传输到服务器端,服务器端再将这一个字符发回来,rlogin再显示到用户屏幕上。这样一个字节的字符却需要20字节的IP+ 20字节的TCP头,这样的传输效率非常低下,只有 1/41 = 2.43%

更要命的是,那时网络带宽特别窄,这样的传输模式很容易将窄窄的带宽挤满而丢包,再重传、再丢包的恶性循环。

于是Nagle发明了一个算法,针对交互式应用,将用户敲入的字符缓存一下,聚集了几个字符放在一起发送,这样传输效率则高得多,唯一的不足是,可能会有一些延迟。

为了避免延迟过大,等待用户时间由定时器控制,比如100-200毫秒,定时器到了,立马将缓冲区的数据发送出去。

但记住一点,Nagle算法是时代的产物,因为当时网络带宽有限。而当前的局域网、广域网的带宽则宽裕得多,所以目前的TCP/IP协议栈默认将Nagle算法关闭,即通过SO_NODELAY = 1

这就好比,现在老王用一辆卡车运一只螃蟹,走沿海高速也不会堵,尽管这听起来很荒诞…

posted @ 2020-10-10 09:44  熊鑫xxx1x  阅读(485)  评论(0)    收藏  举报