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

news/2024/5/17 16:16:47 标签: linux, tcp, struct, java, server, 服务器


今天试着自己实现一个server,用50个进程每个10000个connect,当server接收到的连接数到28280的时候,client出现错误:
部分进程返回错误:99
ERR:File:client.cpp LINE:16 connect failed! msg:99: Cannot assign requested address
部分进程返回错误:110
ERR:File:client.cpp LINE:16 connect failed! msg:110: Connection timed out
之后找到下面的文章。


http://www.cnblogs.com/yoleung/articles/1288568.html

可能牛人都知道怎么设置,只不过将解决思路记录一下。性急的人看最后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 :)

http://www.niftyadmin.cn/n/739464.html

相关文章

Too many open files 问题的解决

2008-10-10 14:42在Linux下&#xff0c;我们使用ulimit -n 命令可以看到单个进程能够打开的最大文件句柄数量(socket连接也算在里面)。系统默认值1024。注意这个问题和Too many open files in system 错误的差别&#xff0c;将在下一篇介绍。对于一般的应用来说(象Apache、系统…

Too many open files in system 错误处理

转载加自己整理编辑。 root下设置完/etc/sysctl.conf,键入 #su - oracle&#xff0c;显示 su: /bin/bash: Too many open files in system 不得已&#xff0c;查看原因&#xff0c;cat /home/oracle/.bash_profile: kernel.sem1055 32000 100 128 kernel.shmmax2147483648 fs.f…

院士教你读文献

无论题目从何而来&#xff0c;都必需紧密追踪当前有关科学领域发展的动向。从研究 生时代开始&#xff0c;在导师 教导下&#xff0c;以周围同学为榜样&#xff0c;我就养成了每周必定去图书 馆浏览最新期刊的习惯&#xff0c;几十年如一日&#xff0c;雷打不动。如果确实有事…

Rsync 参数详解

Rsync 参数详解 在对rsync服务器配置结束以后&#xff0c;下一步就需要在客户端发出rsync命令来实现将服务器端的文件备份到客户端来。rsync是一个功能非常强大的工具&#xff0c;其命令也有很多功能特色选项&#xff0c;我们下面就对它的选项一一进行分析说明。 Rsync的命令…

活动开发总结

1. 对可能存在并发问题的地方&#xff0c;一定要先考虑清楚&#xff0c;如何有效地控制并发&#xff0c;以便检查并且发现问题。 2. 对于每一个需要控制变量和输入数据范围的地方&#xff0c;做到最小范围严格控制&#xff0c;不要用过大的接口检查&#xff0c;比如条…

开始工作之后的十个不要

虽然我已经工作两年了&#xff0c;并且在工作中一直都很上进&#xff0c;可是这篇文章对我现在依然很受用&#xff0c;希望大家用心阅读&#xff0c;或许对你有帮助.。第一&#xff1a;不要认为停留在心灵的舒适区域内是可以原谅的。 每 个人都有一个舒适区域&#xff0c;在这个…

Linux共享库的加载与使用

采用下面几个函数加载动态库 头文件&#xff1a;dlfcn.h 2.1.1 dlerror 原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功. 2.1.2 dlopen 原型为: void *dlopen (const char *filename, int…

心沉下来,多观察,多学习!!不抱怨!!

我的助理辞职了&#xff01;——我想大家对这篇文章应该很有感触 来源&#xff1a;秦启威的日志 当时公司招了大批应届本科和研究生毕业的新新人类。平均年龄25岁。那个新的助理&#xff0c;是经过多次面试后&#xff0c;我亲自招回来的一个女孩。名牌大学本科毕业&#xff0c;…