原文:http://blog.csdn.net/kobejayandy/article/details/46989465
#include<sys/socket.h>
int listen(int sockfd, int backlog);
本函数的第二个参数规定了内核应该为相应套接口排队的最大连接个数,一般为以下两个队列的大小之和,即未完成三次握手队列 + 已经完成三次握手队列
为了更好的理解backlog参数,我们必须认识到内核为任何一个给定的监听套接口维护两个队列:
1、未完成连接队列(incomplete connection queue),每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接口处于SYN_RCVD状态。
2、已完成连接队列(completed connection queue),每个已完成TCP三路握手过程的客户对应其中一项。这些套接口处于ESTABLISHED状态。
当来自客户的SYN到达时,TCP在未完成连接队列中创建一个新项,然后响应以三路握手的第二个分节:服务器的SYN响应,其中稍带对客户SYN的ACK(即SYN+ACK)。这一项一直保留在未完成连接队列中,直到三路握手的第三个分节(客户对服务器SYN的ACK)到达或者该项超时为止(曾经源自Berkeley的实现为这些未完成连接的项设置的超时值为75秒)。如果三路握手正常完成,该项就从未完成连接队列移到已完成连接队列的队尾。当进程调用accept时,已完成连接队列中的队头项将返回给进程,或者如果该队列为空,那么进程将被投入睡眠,直到TCP在该队列中放入一项才唤醒它。
linux系统设置未连接队列最大数限制
linux系统tcp /ip协议栈有个选项可以设置未连接队列大小限制tcp_max_syn_backlog
可以通过命令:cat /proc/sys/net/ipv4/tcp_max_syn_backlog 查看
Linux 系统中提供somaxconn这个参数,它定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128
可以通过命令: cat /proc/sys/net/core/somaxconn 查看
nginx 服务器设置backlog为512
accept
服务端listen之后,会接着调用accept函数来产生一个新的socket以来对请求进行处理。但是listen的时候就已经有了一个旧的socket绑定了80端口,这时accept产生的socket系统还是会分配80端口,一个指定的端口号不能被多个应用程序共用是指多个进程,也就是不同进程之间不能共用一个端口,但是同一个进程内部多个socket可以同时绑定一个端口,服务端会根据socket对应的源端口和源IP来区分接收的数据包来自哪个socket!