在C语言中进行套接字编程时,listen()函数中的队列长度是什么?

10

我在Linux下编写了两个代码(server.cclient.c)。一个用于UNIX域AF_UNIX,另一个用于INTERNET域AF_INET。两者都运行良好!

listen()两个服务器中都被调用,并且用于backlog队列长度为3

listen(sockfd, 3);  

在UNIX域(AF_UNIX)中: 当一个客户端连接到服务器时,如果我尝试连接更多的客户端到服务器,则会有三个客户端被保留在队列中,第四个请求会被拒绝。(正如我所希望的 - 3个在等待队列中)

在INTERNET域(AF_INET)中: 超过三个请求会被保留在一个挂起队列中。

即使后台队列长度为三,为什么第四个客户端请求没有被拒绝?listen()(和其他函数)的行为为什么取决于协议?


我真的不太明白你的意图...为什么你会因为队列已满就想拒绝一个客户呢? - Karoly Horvath
1
@KarolyHorvath:我的意思是,如果我给出等待队列长度,它应该被拒绝。我想了解这个问题。 - Grijesh Chauhan
7
我认为任何不按我们期望的方式运作的API参数都应该让我们感到不安,因为这意味着我们不理解它。 - Kylotan
2个回答

13
操作系统实际上会使用比listen()指定的更大的队列来处理传入的TCP连接。这个队列有多大取决于操作系统。
 listen(int socket_fd, int backlog)  

对于给定的侦听套接字,内核维护两个队列。
  1. 不完整连接队列 - 已收到 SYN 但三次握手(TCP)尚未完成。(SYN_RCV 状态)
  2. 完整连接队列 - 三次握手已完成。(ESTABLISHED 状态)
backlog 参数历史上指定了这两个队列的总和。但是没有正式定义 backlog 的含义。
Berkeley 派生的实现会为 backlog 添加一个调整因子。因此,总队列长度为 factor * backlog

在W. Richard Stevens的书中,有一份非常详细和深入的解释。此外,在Stevens、Fenner和Rudoff的 "Unix Network Programming: The Sockets Network API",第1卷,第3版,第108页中可以找到七个操作系统的值表。


1
例如,在Linux 2.4.7上,将listen()函数的backlog参数设置为3会导致最多排队6个连接。 - Seg Fault
1
CentOS 6.6 2.6.32-504.el6.x86_64 backlog队列是backlog参数+1。 - adrianlzt

4

该平台有权根据其最小值和默认值调整指定的积压量。现在默认值更像是500而不是5,这是从大约1983年开始的。您不能依赖它是您指定的值,也没有API可以查找它的实际值,也没有明显的合理应用原因希望它比默认值更短。


有些人试图将其用作并发连接数的限制。但实际上它并不是。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接