TCP recv 出来的数据会错乱吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
z1113456051
V2EX    问与答

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

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

    服务器(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
    deep89381
        1
    deep89381  
       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     Solana     992 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 19:19 PVG 03:19 LAX 11:19 JFK 14:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86