networkprogramming icon indicating copy to clipboard operation
networkprogramming copied to clipboard

有关tcp_max_syn_backlog不对SYN_RECV队列限制的讨论

Open yangbodong22011 opened this issue 7 years ago • 7 comments

看了你的笔记,我运行了你的代码,我这边不断启动client连接server,SYN_RECV状态的连接数是不断上升的。

uname -a Linux centos-linux.shared 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

运行过程

  1. python server.py
  2. watch -n 1 "sudo netstat -natp | grep 7777" // 使用watch命令监控状态
  3. python client.py & // 不断执行多次

client_test

所以我觉得你一定是实验中什么环节错误了,tcp_max_syn_backlog参数即使内核版本不同,也不会随便改含义的,再确定下你的实验步骤。

yangbodong22011 avatar Mar 25 '18 16:03 yangbodong22011

我这边又测了一下, 结果还是和原先一样, 这次我分别在两台机器上测的... 下面这张是listen(2)的截图, 在全连接队列已满的情况下, 又同时启动了4个client.py, 只能出现2个SYN_RECV连接. listen 2

然后下面这张是listen(5)的, 这次启动了6个, 最多出现5个SYN_RECV(只不过很快就变成了4个). listen 5

这次我没有限制tcp_max_syn_backlog的值, 默认为128.

generals-space avatar Mar 26 '18 02:03 generals-space

好吧,我明确下场景。

下面这张是listen(2)的截图, 在全连接队列已满的情况下, 又同时启动了4个client.py, 只能出现2个SYN_RECV连接.

如果listen(2)的话,按照你的server.py程序,服务端会accpet一次(代码第9行) 正常情况下会出现4条ESTABLISHED状态连接,分别是:

  • 已经完成连接的ESTABLISHED:1条
  • 处于ESTABLISHED队列 :3条(backlog+1)
    目前这一步是正确的哈?

然后你又启动了4个client再去连,只会出现2个SYN_RECV

yangbodong22011 avatar Mar 26 '18 05:03 yangbodong22011

是的, 多余的2个连接压根就没出现(在这4个客户端那边查看时, 连接状态都是ESTABLISHED, 不过connect函数一直没能返回).

generals-space avatar Mar 26 '18 06:03 generals-space

connect返回了,只是在read()函数那里读数据,因为没有数据阻塞了,你在connect()之后加输出就可以看到了。

conn_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn_fd.connect(('127.0.0.1', 7777))
print("connect returned")

原因见这里:https://blog.csdn.net/yangbodong22011/article/details/69802544

yangbodong22011 avatar Mar 26 '18 11:03 yangbodong22011

OK, 纠正一下, 之前的两次测试分别在Fedora 24和Ubuntu 16.04下进行, 都是桌面版.

刚才又尝试在CentOS7下做了一遍(也是桌面版)...这次listen(2)没有限制住, 多次执行client.py产生了多个SYN_RECV的连接. 这也推翻了我之前backlog参数影响两个队列长度的结论. 尴尬.

不过tcp_max_syn_backlog内核参数也没能限制住SYN_RECV的长度, 等我明天再试试.

generals-space avatar Mar 26 '18 16:03 generals-space

不过tcp_max_syn_backlog内核参数也没能限制住SYN_RECV的长度, 等我明天再试试.

没能限制住?这个是指你启动超过了128个client,同时SYN_RECV队列长度超过了128?

我觉得版本应该不影响的,即使不同内核版本策略有更新,但是SYN_RECV队列总是要的,而且长度总是需要控制的,用uname -a贴下你不同发行版上Linux内核版本。

$ uname -a

yangbodong22011 avatar Mar 27 '18 00:03 yangbodong22011

内核版本 CentOS7: uname-centos7 Ubuntu16.04: uname-ubuntu16 04 Fedora24: uname-fedora24


之所以说没能限制住(CentOS 7下), 是因为我手动将tcp_max_syn_backlog修改成了5(listen(2)), 然后在全连接队列已满的情况下, 又同时启动了15个客户端, 然后最多出现了9个SYN_RECV的连接. sysctl

tim 20180330155704

generals-space avatar Mar 30 '18 07:03 generals-space