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


    在实现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接口函数的第二个参数。但是不能太长,维护队列需要成本,排在队尾的连接需要等待的时间可能也比较长,原本对方就可能比较急,等的时间太长会失去连接的意义。

  • 相关阅读:
    Java - List排序
    ⑯、企业快速开发平台Spring Cloud之HTML 总结
    npm 常用命令
    Redis-浅谈主从同步
    Linux 图形界面配置RAID
    Python 通过selniumwire调用企查查原生接口抓取企查查公开企业信息全过程——以抓取成都500万家企业为例
    MyBatis入门案例及实现增删改查
    React Context源码是怎么实现的呢
    Tkinter学习笔记(一):完成文件选择和保存对话框
    【Linux】unzip 解决 replace __MACOSX/xxx? [y]es, [n]o, [A]ll, [N]one, [r]ename
  • 原文地址:https://blog.csdn.net/challenglistic/article/details/126583190