关于计算机网络 tcp 协议,我有个问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
wtmlmz
V2EX    程序员

关于计算机网络 tcp 协议,我有个问题

  •  1
     
  •   wtmlmz 2023-04-23 11:04:25 +08:00 2124 次点击
    这是一个创建于 970 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当 tcp 接受方的半连接和全连接队列满的时候,发送方再发送数据为什么会丢包,而不是返回 RST 呢?

    6 条回复    2023-04-23 16:37:10 +08:00
    ohwind
        1
    ohwind  
       2023-04-23 11:06:41 +08:00
    By ChatGPT:
    当 TCP 接受方的半连接队列和全连接队列都满了,而发送方继续发送数据时,TCP 接受方将不再向发送方发送 ACK 确认消息。因为 TCP 使用滑动窗口协议,它依赖于接收方发送 ACK 确认消息来告诉发送方有多少数据已经被成功接收。如果接收方不再发送 ACK 确认消息,发送方会认为接收方已经收到了所有数据,并且没有发生丢失,因此发送方不会发送 RST 消息。

    当发送方继续发送数据时,这些数据将继续填满网络缓冲区。一旦缓冲区已满,新的数据包将被丢弃。这是因为 TCP 协议有一个拥塞控制机制,它会根据网络的拥塞程度来控制发送方的数据发送速率。当网络拥塞时,TCP 会减慢发送速度以避免进一步的网络拥塞。当缓冲区已满时,这被视为一种拥塞迹象,TCP 会将其解释为网络拥塞,并将减慢发送速度。

    因此,当 TCP 接收方的队列已满时,发送方会继续发送数据,但这些数据将被丢弃,直到接收方能够接受更多数据。这样可以避免网络拥塞,并确保数据传输的可靠性。
    handshake
        2
    handshake  
       2023-04-23 11:53:03 +08:00
    满了就只能丢弃,这样发送方的拥塞控制机制才会知道丢包了,等待重发;如果发送 RST 就直接断了
    handshake
        3
    handshake  
       2023-04-23 11:54:11 +08:00
    满了就只能丢弃,这样发送方的拥塞控制机制才会知道丢包了,等待重发;如果发送 RST 就直接断了,所以 RST 只有新建立的连接才会收到
    artnowben
        4
    atnowben  
       2023-04-23 12:00:35 +08:00
    这个与实现是很相关的,一般如果接收缓冲区满了,可以回一个 ACK ,而不是 RST 。
    如果对这些实现细节感兴趣可以看看 freebsd 的实现,小型的实现可以看看 dperf https://github.com/baidu/dperf
    liuxu
        5
    liuxu  
       2023-04-23 12:16:53 +08:00
    了解下 /proc/sys/net/ipv4/tcp_abort_on_overflow ,默认 0 是 drop 包,置 1 为 rst

    这种情况发生在 server 端进程无法快速消费内核请求队列,内核队列满后:

    server 端内核 drop 包,client 因为没收到回复会重发,重发有时间间隔,server 端再次收到请求时,此时 server 端进程可能已经消费了内核的请求队列,有空余的空间给重发的请求
    server 端内核 rst 包,client 收到 rst 包会直接 close 连接,这样 client 代码需要自己不断重连


    linux 不建议置 1 返回 rst

    https://man7.org/linux/man-pages/man7/tcp.7.html
    linuxyz
        6
    linuxyz  
       2023-04-23 16:37:09 +08:00
    问题可能有点歧义,你这里指已经三次握手完成的 TCP session ? 还是新的 TCP 握手?

    对于已经建立的连接: 如果接收端的缓冲区满了,应该会有 ACK 回应标明 WindowSize 为 0 。
    回 RST 就会导致发送端关闭 TCP session 。但当前的情况仅仅是通信拥塞了而已,在接受端的 App read 了 socket 的数据之后是可以恢复的。

    如果是建立新的 TCP session, 用户的程序 accept 不够快,listen 的半开 socket 队列满了,我感觉应该和实现有关,不过大概率行为应该是啥也不发。毕竟 TCP session 还没完成。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5192 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:51 PVG 16:51 LAX 00:51 JFK 03:51
    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