全/半连接队列(Linux环境下listen函数的第二个参数的意义)

本文解析了TCP通信中的listen函数作用及参数意义,详细介绍了全连接队列与半连接队列的概念,解释了为何需要全连接队列及其长度限制的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实现TCP通信的时候,在调用socket函数创建套接字以后,需要调用listen接口函数来将套接字设为监听状态,listen函数的第一个参数是文件描述符fd,第二个参数则是可以额外建立的连接数


目录

一、验证第二个参数

二、全连接队列 和 半连接队列

三、为什么需要全连接队列?

四、为什么全连接队列不能太长?


一、验证第二个参数

我们的验证很简单,我们先将第二个参数设为1,即额外连接数是1,因此实际上允许建立的连接数为2(额外连接数+1)。下面沿用之前写好的TCP通信代码。

先启动服务端,然后多开三个窗口作为三个客户端。此时我们再开一个窗口输入 netstat -ntp 来查看连接状态。我们会发现,有一个连接处于SYN_RECV的状态,因为上层限制了连接建立成功的个数是 2 个,所以只会存在两个连接是ESTABLISHED状态。

 

二、全连接队列 和 半连接队列

实际上,连接状态即便是变为了ESTABLISHED,也不代表就能立马进行通信。同意连接是传输层的决策,但是上层此时可能忙于处理其他业务,无暇顾及,此时就会把状态为ESTABLISHED的连接放入“全连接队列”等待,等到上层调用accept的时候,就会从全连接队列中 取走连接并返回文件描述符。(全连接队列中的连接个数 = listen函数的第二个参数+1)

由于上层限制了每次可以建立成功连接的个数,因此溢出的连接只能停留在 SYN_RECV 状态,这些连接会进入 半连接队列 等待,等全连接队列中空出来一个位置,半连接队列中的某个连接就会进入全连接队列。(半连接队列中的连接个数是算法形成的,不同的OS可能不同)。

由此可以知道,

  • 全连接队列(accpetd队列)(用来保存处于established状态,但是应用层没有调用accept取走的请求)
  • 半链接队列(用来保存处于SYN_SENT和SYN_RECV状态的请求)

三、为什么需要全连接队列?

以一家火锅店为例,这家店生意很火,每天座无虚席。

店家不在店外摆凳子,想进店的顾客都只能站在外面等,于是顾客不断流失。突然有一天,店里没客人了,巧的是这个时候店外也没有顾客想要进来,这种状况持续了很久。

自此店家开始在店外摆凳子,提供免费饮料,顾客很乐意在外面等。当店内有客人离席的时候,就通过叫号的方式招呼顾客进来。

店外队列 —— 全连接队列                店内 —— 上层服务

需要全连接队列的原因是,当有连接被释放的时候,就可以让新的连接进入上层,保证了上层的资源始终是被100%利用的。

四、为什么全连接队列不能太长?

全连接队列的长度是上层,也就是用户设置的,即listen接口函数的第二个参数。但是不能太长,维护队列需要成本,排在队尾的连接需要等待的时间可能也比较长,原本对方就可能比较急,等的时间太长会失去连接的意义。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值