Listen第二个参数的值介绍

Socket编程中listen的第二个参数

一、Listen函数的原型

int listen(int sockfd, int backlog);

  • 第一个参数我们都知道是socket返回的描述符
  • 第二个参数表示什么呢,之前一直以为是connet的连接数量,但后面写小项目的时候发现并不是。

二、Listen函数的第二个参数详解

Listen第二个参数的值介绍
这张图是展示的三次握手的过程,这里我们要关注两个队列

  • 未完成三次握手的队列:每个这样的SYN分对应其中的一项,某个客户端发起了请求并到达服务端,而服务器正在等待处理对应的三次握手过程。这些套接口处于SYN_RCVD。
  • 已完成队列:每个都已经完成了三路握手过程的客户端对应其中一项。这些套接口处于ESTABLISHED。

如何理解这两个队列:

比如未完成的队列设置为50,现在有并发100个请求,假如系统处理速度缓慢,则系统会做这几件事

  1. 因为未完成的队列设置为50个,系统会先拿50个请求来处理三次握手,其他的请求直接拒绝。TCP会忽略该分节,也就是不发送RST(RST为重置连接,一般是在FIN之后才会出现为1的情况,表示的是连接重置。一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接),这样客户端将重新发送SYN请求连接,期望在未完成的队列中找到位置。
  2. 每处理完一个三次握手动作,系统就会让出一个未完成队列的位置,来接受一个SYN请求。
  3. 完成三次握手的请求放到已完成的队列中

在man手册中有这么一段话
The backlog argument defines the maximum length to which the queue of
pending connections for sockfd may grow. If a connection request
arrives when the queue is full, the client may receive an error with an
indication of ECONNREFUSED or, if the underlying protocol supports
retransmission, the request may be ignored so that a later reattempt at
connection succeeds.
大致的意思是backlog定义的是队列的最大长度,当队列已满时还有请求到达,客户端可能会接收到错误消息,如果基础协议支持,则指ECONNREFUSED 或者重新传输时,请求可能会被忽略,以便稍后在连接成功。
下面还有一段
The behavior of the backlog argument on TCP sockets changed with Linux
2.2. Now it specifies the queue length for completely established
sockets waiting to be accepted, instead of the number of incomplete
connection requests. The maximum length of the queue for incomplete
sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When
syncookies are enabled there is no logical maximum length and this set‐
ting is ignored. See tcp(7) for more information.
大致意思是在三次握手成功后的队列,如果系统还没有通过accept调用这个队列中的数据,一旦这个队列满了。未连接的请求过不来,导致未完成三次握手的请求会超时或拒绝,如果系统调用了accept队列接收数据,就会把接受的请求移除已完成队列,这时已完成队列又可以使用。
最后补充,如果开启了syncookies,则忽略listen第二个参数。

总结

  1. 内核用了两个队列来处理,当并发请求超过能处理的上限时过滤一部分,防止盲目等待。
  2. 第二个参数跟系统连接数无关,相当于设置一个瞬间能处理的阈值
  3. 一般可以开启syncookies,这样可以不太关心listen第二个值
上一篇:redis配置文件(部分)


下一篇:Video about Agile Testing