在 Linux 网络编程里,“backlog 变小”通常说的是 listen(socket, backlog) 里的 backlog 参数实际生效的值比设置的小。这不是你代码写错了,而是 Linux 内核做了限制或语义变化。
下面按常见原因解释:
在 Linux 2.2 之后,listen() 的 backlog 不再同时表示两个队列,而是:
backlog = 已完成连接(ESTABLISHED)队列的最大长度参考值
而 半连接队列(SYN_RECV) 由:
/proc/sys/net/ipv4/tcp_max_syn_backlog
控制。
所以你设置的 backlog 只影响 accept 队列。
Linux 实际生效的 backlog 是:
实际 backlog = min(backlog, net.core.somaxconn)
默认:
net.core.somaxconn = 128
所以即使你写:
listen(fd, 1024);
实际可能只有 128。
查看:
cat /proc/sys/net/core/somaxconn
修改:
sysctl -w net.core.somaxconn=1024
在一些老内核中:
实际队列长度 = backlog * 1.5 取整
不过现代内核基本已取消。
如果 SYN 很多:
tcp_max_syn_backlog 小tcp_syncookies=1会导致 连接还没进 accept 队列就被丢弃或走 cookie
查看:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
即使 backlog 很大,如果:
队列很快被占满,新连接被 直接丢弃(RST)
这不是 backlog 变小,而是 用满了。
在:
somaxconn 可能被平台覆盖成较小值(如 128 或 512)
可以看:
ss -lnt
示例:
LISTEN 0 128 0.0.0.0:8080
第二个数就是 当前 accept 队列上限
如果你设了 1024 但显示 128,就是被 somaxconn 限制了。
Linux 中 backlog 变小,99% 是因为被
net.core.somaxconn截断了。
如果你愿意,可以告诉我:
我可以给你一个精确调优方案。