由一个经典问题来引出:一台机器最多可以建立多少tcp连接?
这个问题基本都是从server的角度来回答,因为很少会有客户端需要建立多个连接。
需要记住:
client_ip:client_port <---> server_ip:server_port,一个四元组可以确定一个连接
一.对于单机server,单机可以接受的最大连接数是多少?
65536是一个经典错误答案.
理论上是受系统支持的最大打开文件描述符的数目限制;实际则受到系统资源的各种限制。之前转过一篇淘宝探索单机server 支持200M连接的尝试。
对于从同一个listen的socket accept进来的连接,是本机端口号都是同一个端口号,都是listen之前bind的那个端口号。从同一个listen的socket可以接受的连接实际上也远大于65536
对于单机server来讲,通常server_ip和server_port是固定的,client_ip和client_port都是可变量,可变数目远大于65536。实际上server_ip也可以通过多网卡,虚ip等手段来变化
二.对于单机client,单机可以发起的最大连接数是多少?
1.client连接的只是一个对端server,即对端ip:port是确定的,只有一个。
这时,要受到系统端口号的限制,每发起一个新的连接,就要占用一个新的端口号。这就是65536这个数字的由来,因为端口号是16位无符号整数,0-65535之前变化。
但实际最大连接数并到不了65536,还要受到net.ipv4.ip_local_port_range 这个范围的限制,自己的程序只能使用这个范围内的端口号。
这种情况下,通常server_ip,server_port,client_ip都是固定的,可变的只有client_port,所以受到端口号数目的限制。实际上client_ip也可以通过多网卡,虚ip等手段来变化
2.client连接的是多个server,即对端ip:port有多个可以同时连接
这时的答案和单机server的情况是一样的,理论上是受系统支持的最大打开文件描述符的数目限制;实际则受到系统资源的各种限制。
对于这种情况下,只有client_ip是固定的,server_ip server_port client_port都是可变量,可变数目远大于65536,但在实际编程处理时,需要注意如何支持使用相同的本地ip和port向不同的远端发起连接,即支持:
client_ip:client_port ------- server_ip1:server_ip1
client_ip:client_port ------- server_ip2:server_ip2
这样的情况,需要设置客户端socket 的SO_REUSEADDR选项,即可使用相同的本地ip和port向不同的远端发起连接
SO_REUSEADDR通常只在server端设置,用来能使server快速重启
Stevens的Unix网络编程中说,SO_REUSEADDR可以用在以下四种情况下:
1.当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
2.SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情
3.SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。
4.SO_REUSEADDR允许完全相同的地址和端口的重复绑定。正常只用于UDP的多播
测试了ubuntu和centos下的nc程序,作为客户端时都是没有设置SO_REUSEADDR选项的.