linux 发送缓冲区 状态,一个 TCP 发送缓冲区问题的解析

博客讨论了一个TCP发送缓冲区问题,当客户端每秒发送1024字节报文时,发现Send-Q值超过了设置的SO_SNDBUF值。内核实际上将SO_SNDBUF翻倍来考虑额外开销,但即便如此,仍无法解释最终的Send-Q值。文章深入探讨了内核如何处理sk_buff,以及GSO功能在其中的影响,揭示了内核如何在某些情况下允许Send-Q超过设置限制。
摘要由CSDN通过智能技术生成

最近遇到一个问题,简化模型如下:

d95e05abfac1ae91f22023262a0a4676.png

Client 创建一个 TCP 的 socket,并通过 SO_SNDBUF 选项设置它的发送缓冲区大小为 4096 字节,连接到 Server 后,每 1 秒发送一个 TCP 数据段长度为 1024 的报文。Server 端不调用 recv()。预期的结果分为以下几个阶段:

Phase 1 Server 端的 socket 接收缓冲区未满,所以尽管 Server 不会 recv(),但依然能对 Client 发出的报文回复 ACK;

Phase 2 Server 端的 socket 接收缓冲区被填满了,向 Client 端通告零窗口(Zero Window)。Client 端待发送的数据开始累积在 socket 的发送缓冲区;

Phase 3 Client 端的 socket 的发送缓冲区满了,用户进程阻塞在 send() 上。

实际执行时,表现出来的现象也"基本"符合预期。不过当我们在 Client 端通过 ss -nt 不时监控 TCP 连接的发送队列长度时,发现这个值竟然从 0 最终增长到 14480,它轻松地超了之前设置的 SO_SNDBUF 值(4096)

# ss -nt

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 0 192.168.183.130:52454 192.168.183.130:14465

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 1024 192.168.183.130:52454 192.168.183.130:14465

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 2048 192.168.183.130:52454 192.168.183.130:14465

......

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 13312 192.168.183.130:52454 192.168.183.130:14465

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 14336 192.168.183.130:52454 192.168.183.130:14465

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 0 14480 192.168.183.130:52454 192.168.183.130:14465

有必

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值