如何在客户端无错误地建立大量连接

时间:2018-03-27 09:31:29

标签: sockets go

我已经在golang中编写了一个程序,通过linux随机选择的本地端口向不同的远程ip发出2000qps的请求,并在建立连接后立即关闭请求,但是仍然会定期遇到bind: address already in use错误

我做了什么:

  1. net.ipv4.ip_local_port_range是15000-65535
  2. net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30
  3. 以上是sockstat:

    sockets: used 1200 TCP: inuse 2302 orphan 1603 tw 40940 alloc 2325 mem 201
    

    我还没弄清楚为什么在内核选择可用的本地端口时仍然会出现此错误,内核是否会返回正在使用的端口?

1 个答案:

答案 0 :(得分:0)

这是2012年的一个很好的答案:

https://serverfault.com/questions/342741/what-are-the-ramifications-of-setting-tcp-tw-recycle-reuse-to-1#434669

截至2018年,tcp_tw_recycle仅存在于sysctl二进制文件中,否则将从内核中消失:

https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=tcp_tw_recycle&type=

tcp_tw_reuse仍在使用,如上面的答案中所述:

https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c#L128

但是,正在使用TCP_TIMEWAIT_LEN:

https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=TCP_TIMEWAIT_LEN&type=

该值是硬编码的:

https://github.com/torvalds/linux/blob/master/include/net/tcp.h#L120

和tcp_fin_timeout指的是不同的状态:

https://github.com/torvalds/linux/blob/master/Documentation/networking/ip-sysctl.txt#L294

可以相对安全地将本地端口范围更改为1025-65535。

对于踢,如果有这种情况,这个客户端正在与我控制的服务器和网络通信,我会构建一个新的内核,其中包含一个不符合规范的TCP_TIMEWAIT_LEN,也许还会使用tcp_max_tw_buckets:

https://github.com/torvalds/linux/blob/master/Documentation/networking/ip-sysctl.txt#L379

但在其他情况下这样做 - 如果此客户端在NAT后面并与普通公共服务器通信 - 可能会造成破坏性。