V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
z1113456051
V2EX  ›  问与答

TCP recv 出来的数据会错乱吗?

  •  
  •   z1113456051 · 2021-08-13 13:56:51 +08:00 · 835 次点击
    这是一个创建于 958 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务器(CentOS 6.10)出现了偶现的 TCP 数据解包失败,用 tcpdump 抓包看到,出问题每次都是在 Seq 不连续的那个包。

    例如收到包的顺序是 3 4 2 。recv 出来的数据顺序也是 2 3 4,但是这时候的 3 的数据内容就错乱了。

    日志加在 /netio/epoll/tcpcarrier.cpp 。TCPCarrier::OnEvent 的 ReadFromTCPFd 的下一行。

    目前怀疑 recv 和 iobuffer,已经补了日志在 recv 的下一行,不过这个问题还没有再次出现。

    这个问题是偶现的,并不是每次出现[TCP Previous segment not captured]都会有问题

    取数据代码 recv(fd, (char *)(_pBuffer + published), expected, MSG_NOSIGNAL)

    第一次问题

    // 这个包还是正常的。抓包数据和程序内 recv 后的日志都还是对的上的

    68691 1885.443261 TCP 102 37001 → 33118 [PSH, ACK] Seq=1965201 Ack=1801824 Win=12987 Len=36 TSval=206775456 TSecr=2087966452 data:2400000010400000000000000000000013204000f5340a616d880000000001005f8e1b00

    68692 1885.444510 TCP 66 37001 → 33118 [ACK] Seq=1965237 Ack=1801882 Win=12987 Len=0 TSval=206775457 TSecr=2087966481

    // 从这里开始不对了

    // 这个包的数据在日志中搜不到了(应该是这个包的数据错乱了,放在 recv 的数据中间)

    68693 1885.593978 TCP 115 [TCP Previous segment not captured] 37001 → 33118 [PSH, ACK] Seq=1965273 Ack=1801882 Win=12987 Len=49 TSval=206775606 TSecr=2087966481 data:310000001a400000000000000000000001a60f0a617ecf000000000000b9227f00000001004ce979000100000000000000

    68694 1885.599328 TCP 115 37001 → 33118 [PSH, ACK] Seq=1965322 Ack=1801882 Win=12987 Len=49 TSval=206775612 TSecr=2087966631 data:310000001a400000000000000000000001a60f0a617ecf000000000000b9227f0000000100c9f76c000100000000000000

    68695 1885.794432 TCP 102 [TCP Retransmission] 37001 → 33118 [PSH, ACK] Seq=1965237 Ack=1801882 Win=12987 Len=36 TSval=206775807 TSecr=2087966637 data:24000000104000000000000000000000b9227f00a60f0a617ecf0000000001005c817b00

    // 这是 recv 后日志的打印,这一次一共获得了 3 个包的数据,68695 在这次 recv 的数据的前面,68694 在后面。但是中间多出了一段乱的数据,同时 68693 的数据找不到了,中间错乱的数据长度还正好和它一样。

    24000000104000000000000000000000B9227F00A60F0A617ECF0000000001005C817B00A061DFDFB279F68C070442DA5C819A00100021927FAC089265FA711C8E5563F23330ED971033E5AD86F70BC9A62C5D8CB0310000001A400000000000000000000001A60F0A617ECF000000000000B9227F0000000100C9F76C000100000000000000

    第二次问题

    // 这个包的 tcpdump 和程序内 recv 后的日志是对的上的

    167466 3133.986731 TCP 94 37001 → 40534 [PSH, ACK] Seq=5021467 Ack=4605653 Win=12482 Len=28 TSval=233223981 TSecr=2114414994 data:1c00000012400000000000000000000043fd7e00c2a10a61cb1d0000

    // 从这里开始不对了

    // 这个包的数据在日志中搜不到了(应该是这个包的数据错乱了,放在这一次 recv 的数据的中间)

    167467 3134.082772 TCP 102 [TCP Previous segment not captured] 37001 → 40534 [PSH, ACK] Seq=5021531 Ack=4605653 Win=12482 Len=36 TSval=233224077 TSecr=2114415046 data:24000000104000000000000000000000123531001e9a0a6171f200000000010017d87d00

    167469 3134.237788 TCP 102 [TCP Retransmission] 37001 → 40534 [PSH, ACK] Seq=5021495 Ack=4605653 Win=12482 Len=36 TSval=233224233 TSecr=2114415124 data:2400000010400000000000000000000040d17d0059710a61914e000000000100fb101b00

    167468 3134.104359 TCP 102 37001 → 40534 [PSH, ACK] Seq=5021567 Ack=4605653 Win=12482 Len=36 TSval=233224099 TSecr=2114415102 data:24000000104000000000000000000000fd053300dd780a61c30300000000010022987900

    // 和第一次差不多,这次 recv 的日志,一次 3 个包的数据,167469 和 167468 的数据是对的分别在收尾。但是中间多出了一段乱的数据,同时 167467 的数据不见了。

    24000000104000000000000000000000FD053300DD780A61C303000000000100229879008060068F405C6A200B0B4F063C85B820014FFCC7E96A28A0036DEE25CD7BED8EDBFD576A2400000010400000000000000000000040D17D0059710A61914E000000000100FB101B00

    3 条回复    2021-08-18 11:47:00 +08:00
    zhuifeng1017
        1
    zhuifeng1017  
       2021-08-14 07:55:05 +08:00
    tcpdump 抓取的是网卡数据,理论上不会有问题。
    问题只可能是 recv 代码问题。考虑多线程,recv 粘包等原因
    z1113456051
        2
    z1113456051  
    OP
       2021-08-14 11:52:33 +08:00
    @zhuifeng1017

    只能先等下一次出问题,这样就能确定 recv 取出来就是错误的了。
    julyclyde
        3
    julyclyde  
       2021-08-18 11:47:00 +08:00
    recv 不可能顺序错乱
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1051 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:15 · PVG 03:15 · LAX 12:15 · JFK 15:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.