listen函数中backlog参数的意义
1)backlog 用于在TCP层接收链接的缓冲池的最大个数,这个个数可在应用层中的listen函数里设置,当客户链接请求大于这个个数(缓冲池满),其它的未进入链接缓冲池的客户端在tcp层上tcp模块会自动重新链接,直到超时(大约57秒后)
2)应用层链接(connect)完成时,要从tcp层的链接缓冲池中移出一个(accept函数实现)
3).backlog是连接请求队列的最大长度
TCP握手的几个阶段
收到客户端的syn请求 ->将这个请求放入syn_table中去->服务器端回复syn-ack->收到客户端的ack->放入accept queue中
在linux里可以简单的认为有2个队列,一个就是在握手过程中的队列,而另一个就是握手成功的队列
而backlog影响的是握手成功的队列
backlog 并不是按照你调用listen的所设置的backlog大小,实际上取的是backlog和somaxconn的最小值
在linux内核2.2版本以后,backlog参数控制的是已经握手成功的还在accept queue的大小。
现在backlog用来确定已完成队列(完成三次握手等待accept)的长度,而不再是已完成队列和未完成连接队列之和(linux 2.2之前)。
未完成队列(incomplete connection queue),每个这样的SYN分节对应其中一项:已由每个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接字处于SYN_RCVD状态。,的长度现在由/proc/sys/net/ipv4/tcp_max_syn_backlog设置,在现在大多数最新linux内核都是默认512,这个设置有效的前提是系统的syncookies功能被禁用,如果系统的syncookies功能被启用,那么这个设置是无效的。Syncookies是在内核编译的时候设置的,查看syncookies是否启动:
cat /proc/sys/net/ipv4/tcp_syncookies
如果是“1”说明已启用,为“0”说明未启用。
那么为syncookies是做什么的呢,为什么它会和未完成队列有关系。简单的说它是为防范SYN Flood攻击的设计。
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
已完成队列(complete connection queue),每个已完成TCP三路握手过程的客户对应其中一项,这些套接字处于ESTABLISHED状态。
继续看backlog,如果我们给listen的backlog参数设值超过了/proc/sys/net/core/somaxconn,那么backlog参数的值为自动被改写为/proc/sys/net/core/somaxconn的值,它的默认大小为128.
2048
cat /proc/sys/net/core/somaxconn
128
查看连接情况
watch "netstat -t -n | grep 9001 | grep -oP '\w+\s*$' | sort | uniq -c"
watch "ss -s"