【问题标题】:TCP messages getting coalescedTCP 消息被合并
【发布时间】:2011-12-14 03:22:31
【问题描述】:

我有一个正在写入网络的 Java 应用程序。它正在 764b +/- 5b 的区域内写入消息。 pcap 显示流正在被 IP 碎片化,我们无法解释这一点。

Linux 2.6.18-238.1.1.el5

strace 显示:

(strace -vvvv -f -tt -o strace.out -e trace=network -p $PID)

1: 2045  12:48:23.984173 sendto(45, "\0\0\0\0\0\0\2\374\0\0\0\0\0\3\n\0\0\0\0\3upd\365myData"..., 764, 0, NULL, 0) = 764
2: 15206 12:48:23.984706 sendto(131, "\0\0\0\0\0\0\2\374\0\0\0\0\0\3\n\0\0\0\0\3upd\365myData"..., 764, 0, NULL, 0 <unfinished ...>
3: 2046  12:48:23.984811 sendto(46, "\0\0\0\0\0\0\2\374\0\0\0\0\0\3\n\0\0\0\0\3upd\365myData"..., 764, 0, NULL, 0 <unfinished ...>
4: 15206 12:48:23.984893 <... sendto resumed> ) = 764
5: 2046  12:48:23.984948 <... sendto resumed> ) = 764

我在捕获网络时看到大于 MTU 的数据包,这导致了碎片。

4809   5.848987 10.0.0.2 -> 10.0.0.5 TCP 40656 > taiclock [ACK] Seq=325501 Ack=1 Win=46 Len=1448 TSV=344627654 TSER=270108068        # First Fragment
4810   5.848991 10.0.0.5 -> 10.0.0.2 TCP taiclock > 40656 [ACK] Seq=1 Ack=326949 Win=12287 Len=0 TSV=270108081 TSER=344627643       # TCP ack
4811   5.849037 10.0.0.2 -> 10.0.0.5 TCP 40656 > taiclock [PSH, ACK] Seq=326949 Ack=1 Win=46 Len=82 TSV=344627654 TSER=270108081    # Second Frag

问题:

1) 似乎服务器试图将两个 sendto() 批处理成一个 IP 数据包,该数据包大于 MTU,因此会产生碎片。为什么?

2) 查看 PID 2046 的 strace 输出,等号 <... sendto resumed> 行之后的数字是发送的总和吗? IE。第 3 行和第 5 行总共发送了 764b?还是每行发送 764 个字节?

3) 是否有任何选项可以传递给 strace 以记录 sendto() 输出的所有?好像什么都找不到。。

【问题讨论】:

    标签: linux pcap fragmentation strace sendto


    【解决方案1】:

    回答您的问题,按顺序:

    1) 使用 TCP 时合并多个发送调用是完全正常的,因为它是流协议,因此不会以任何方式保留用户级发送边界。在您的跟踪中,我没有看到任何 IP 分段(这将是不好的)的证据,只是 TCP 分段(这是完全正常的)。

    2) 是的,这就是大小 - 更具体地说,它报告系统调用在恢复后返回的值。

    3) 您可以使用“-e write=all”或“-e write=”来让 strace 报告整个写入的数据。

    【讨论】:

    • 专门针对 #1 这称为“Nagle 算法”
    • 不是真的 - 合并总是可能的。 Nagle 只是通过有时延迟发送少量数据以希望发送更多可以与之合并的数据来增加它的可能性。
    猜你喜欢
    • 1970-01-01
    • 2011-12-09
    • 2015-05-12
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 2012-07-23
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多