linux tcp端口限制,Linux 向外TCP最大连接只能打开28232个端口限制tuning

可能牛人都知道怎么设置,只不过将解决思路记录一下。性急的人看最后3行就行了。

因为想测试一下java mustang(jdk1.6)使用epoll的性能,Tim最近写了一个Java NIO的client在Linux去连服务器,原理上一个client是可以打开65535个端口的(而且只需要一个线程, nonblocking io就是好),但是每个 Linux client 在打开 28231-28233左右的连接之后就说

Cannot assign requested address

这时候使用 telnet 去连服务器报同样错误:

Unable to connect to remote host: Cannot assign requested address

说明不是Java程序的问题。用 tcpdump 监听了一下,发现没有网络流量,那可能是本地内核的限制了。

用 netstat 去看客户机的显示全部本地端口都使用 30000~60000 左右的。

联想到 Windows 默认 5000 个端口的限制,觉得 Linux 应该也设了一个限制。

在网上google解决办法可能关键词没找好,没发现答案(搜索上面出错那个字符串很难得到答案),只知道这个字符串是error.h里面是 “EADDRNOTAVAIL”。找不到解决办法,只好看 Linux 源代码了,笨人用笨方法

解开Linux 2.6源代码,根据 socket 接口应该看 connect() 的实现

打开 tcp_ipv4.c, 找到

/* This will initiate an outgoing connection. */

int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)

应该就是这里了,看进去, 它调用了另外一个函数

/*

* Bind a port for a connect operation and hash it.

*/

static int tcp_v4_hash_connect(struct sock *sk)

这个函数中间判断了一个sysctl_local_port_range的变量,不符合条件就 return -EADDRNOTAVAIL;

那问题就是 sysctl_local_port_range 了

找下上下文关于 sysctl_local_port_range 的设置

in tcp.c, 这里是设置初始值

void __init tcp_init(void)

/* Try to be a bit smarter and adjust defaults depending

* on available memory.

*/

if (order > 4) {

sysctl_local_port_range[0] = 32768;

sysctl_local_port_range[1] = 61000;

sysctl_tcp_max_tw_buckets = 180000;

sysctl_tcp_max_orphans = 4096 << (order - 4);

sysctl_max_syn_backlog = 1024;

}

注释说程序要改进一下,根据内存的情况来动态分配开多大端口,不过现在的版本是写死的 :(

定义的地方:

/*

* This array holds the first and last local port number.

* For high-usage systems, use sysctl to change this to

* 32768-61000

*/

int sysctl_local_port_range[2] = { 1024, 4999 };

Tim的最终解决办法:因为上面有个注释说可以用 sysctl 来设置,怎么设呢,一行字

echo "net.ipv4.ip_local_port_range = 1024 65000" >> /etc/sysctl.conf; sysctl -p

搞定了,一个client可以发起65000个连接了,写程序的人每天就要面对这些意想不到的问题。

说明:以上方法在 Linux 2.6.9 上通过, 如果你的内核版本不同改了不生效不要来找 Tim :)0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值