socket接收的所有连接都是存放在队列类型的数据结构中,关键问题是这种队列有两个,而且其长度都是可以设置的。
 
分别是下面两个内核参数:
 
/proc/sys/net/ipv4/tcp_max_syn_backlog
 
/proc/sys/net/core/somaxconn
 
其中:
 
 
tcp_max_syn_backlog是指定所能接受SYN同步包的最大客户端数量,即半连接上限;
 
somaxconn是指服务端所能accept即处理数据的最大客户端数量,即完成连接上限。
 
对于没有调优的新装的centOS6.5系统,这两个参数的值都是128。
 
 
 
这么描述虽然精确,但是没有一定基础,不熟练网络编程的人理解起来很费劲。
 
打个简单的比方:
 
某某发布公告要邀请四海之内若干客人到场参加酒席。客人参加酒席分为两个步骤:
 
1、到大厅;
 
2、找到座位(吃东西,比如糖果、饭菜、酒等)。
 
tcp_max_syn_backlog用于指定酒席现场面积允许容纳多少人进来;
 
somaxconn用于指定有多少个座位。
 
显然tcp_max_syn_backlog>=somaxconn。
 
如果要前来的客人数量超过tcp_max_syn_backlog,那么多出来的人虽然会跟主任见面握手,但是要在门外等候;
 
如果到大厅的客人数量大于somaxconn,那么多出来的客人就会没有位置坐(必须坐下才能吃东西),只能等待有人吃完有空位了才能吃东西。
 
那么问题来了:
 
somaxconn是内核里的参数,listen函数有个参数backlog,如果在listen方法里面指定该参数大于somaxconn的值,重新编译并启动程序,服务端所能接收的完整的连接数上限是backlog呢还是somaxconn?
 
答案很简单,listen方法指定的backlog是在用户态指定的,内核态的参数优先级高于用户态的参数,所以即使在listen方法里面指定backlog是一个大于somaxconn的值,socket在内核态运行时还会检查一次somaxconn,如果连接数超过somaxconn就会等待。
 
就相当于主人指定了能有多少座位没用,客人到了现场,准备入座时,还要看酒店的客户经理判断能有多少个座位。
 
 
结论:
 
在没有调优的centOS6.5版本的服务器上,由于受到系统级别的限制,在该服务器上运行的服务端程序,在同一时间,最大只能接受128个客户端发起持久连接,并且只能处理128个客户端的数据通信。