listen() 忽略了 backlog 值

7

据我所知,积压决定了连接队列的大小。在那个时候,任何超过这个大小的额外请求都将被丢弃(这个说法正确吗?)。

现在我有一个非常简单的程序server.c

socket()
bind()
listen(..., 5)
while(1)
{
  accept()
  read()
  write()
  sleep(3)
  close()
}

现在,我一次启动8个客户端连接到这个服务器。令人惊讶的是,服务器服务了所有8个客户端,但实际上它只应该排队5个客户端,剩余的3个客户端请求应该被拒绝。另一个有趣的点是,即使我将此backlog值设置为0,结果仍然相同。然后我尝试注释listen()调用,这样所有8个客户端连接都被拒绝。
请问有人可以对此提供任何意见吗?

你应该将 readwriteclose 放在并发环境中。在你的代码中,当下一个连接被 accept 时,似乎前一个连接已经关闭了。将代码放入线程中,并确保每个连接持续足够长的时间,以确保同时有8个客户端请求你的服务器的情况真正发生。 - Summer_More_More_Tea
我之前测试了 backlog,但是没有得到任何结果。希望现在能够得到答案。 - tuxuday
OP,请您发一下示例代码,这样大家就可以复制粘贴测试了。 - tuxuday
@ Summer_More_More_Tea 由于存在3秒的休眠时间,之前的连接无法立即关闭。由于所有8个请求都在3秒内到达,因此请求已经超过了挂起队列(5)。 - user1409528
可能是listen()忽略了backlog参数?的重复问题。 - ks1322
1个回答

4
backlog参数是关于队列大小的提示。因此,您不能指望它做您所要求的事情。listen()。这个答案似乎涵盖了它。更多信息,请参见我的Ubuntu系统上listen(2)手册页中的引用:backlog参数定义sockfd的挂起连接队列可以增长的最大长度。如果连接请求在队列已满时到达,则客户端可能会收到带有ECONNREFUSED指示的错误,或者如果底层协议支持重传,则可能会忽略该请求,以便稍后重新尝试连接成功。请注意,它的每个地方都说“可能”。

在我的系统中,SOMAXCONN设置为128。那么如果我同时启动超过128个客户端,会出现什么行为? - user1409528
是的,规范确实说支持128个值,但没有实际限制未完成连接的数量。 我假设此规范与您使用的规范类似。 - Francis Upton IV
请查看我的答案修订。 - Francis Upton IV

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