14读缓冲区(滑动窗口)耗尽与write阻塞、拆包、延迟(三)禁用nagle仍发送端沾包

本文设计了一个案例,证明禁用nagle的情况下,并非所有情况都不会导致发送端沾包

在 读缓冲区(滑动窗口)耗尽与write阻塞、拆包、延迟(二)的代码上,使用默认发送缓冲区大小,并禁用nagle,这是第三种情况,前2种在11读缓冲区(滑动窗口)耗尽与write阻塞、拆包、延迟(一)

    //    s.setSendBufferSize(BUFFER_SIZE);

        /**
         * 禁用nagle,可连续发包
         */
        s.setTcpNoDelay(true);

 

服务端,12s后直接打印到:

96
97
98
99
100
101
102   由于各种拆包多了3个包

客户端:

无阻塞直接打印到

send + 97
send + 98
send + 99

Process finished with exit code 0

 

结论:

1 客户端发送缓冲区够大,即使对端窗口耗尽,也没导致write阻塞

再次“证明了接收窗口不够时,一些情况会导致write阻塞,但不是直接因为对端接收窗口不够了,而是因为对端窗口导致本方发送缓冲区积压至满,只要内核发送缓冲区够大,write就能返回,不会由于对端不接收数据而直接阻塞”

2 12s后,服务端开始读,通知客户端有空间了

3 客户端一口气连发一堆,1152+1072*8+272=10000(禁用nagle情况下,发送端也沾包了)

write只是将数据从用户态拷贝到了内核态,不保证能立即发送(报文17 52个字节延迟5s发送),甚至能否发送(超出1152长度的其它包)

5 程序正常结束时tcp连接还会继续保持(本例抓到包了),程序会隐式close socket(本例发出fin包),什么时候发,发之前是否先等缓冲区全部发送完,发fin还是rst,由tcp协议及(默认SoLinger== -1会等,发fin包)控制

 

禁用nagle时同样会有发送端沾包.pcap.zip

posted on 2019-12-15 00:13  silyvin  阅读(288)  评论(0编辑  收藏  举报