IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 【tcp】TCP 半连接队列、全连接队列基本概念 -> 正文阅读

[网络协议]【tcp】TCP 半连接队列、全连接队列基本概念

TCP? 三次握手状态变化

对于客户端:

初始的状态是处于 CLOSED 状态。CLOSED 并不是一个真实的状态,而是一个假想的起点和终点。

客户端调用 connect 以后会发送 SYN 同步报文给服务端,然后进入 SYN-SENT 阶段,客户端将保持这个阶段直到它收到了服务端的确认包。

如果在 SYN-SENT 状态收到了服务端的确认包,它将发送确认服务端 SYN 报文的 ACK 包,同时进入 ESTABLISHED 状态,表明自己已经准备好发送数据。

对于服务端:

初始状态同样是 CLOSED 状态。

在执行 bind、listen 调用以后进入 LISTEN状态,等待客户端连接。

当收到客户端的 SYN 同步报文以后,会回复确认同时发送自己的 SYN 同步报文,这时服务端进入 SYN-RCVD 阶段等待客户端的确认。

当收到客户端的确认报文以后,进入ESTABLISHED 状态。这时双方可以互相发数据了。

当服务端调用 listen 函数时,TCP 的状态被从 CLOSE 状态变为 LISTEN,于此同时内核创建了两个队列:

半连接队列(Incomplete connection queue),又称?SYN 队列

全连接队列(Completed connection queue),又称?Accept 队列

半连接队列

当客户端发起 SYN 到服务端,服务端收到以后会回 ACK 和自己的 SYN。这时服务端这边的 TCP 从 listen 状态变为 SYN_RCVD (SYN Received),此时会将这个连接信息放入「半连接队列」,半连接队列也被称为 SYN Queue,存储的是 “inbound SYN packets”。

服务端回复 SYN+ACK 包以后等待客户端回复 ACK,同时开启一个定时器,如果超时还未收到 ACK 会进行 SYN+ACK 的重传,重传的次数由 tcp_synack_retries 值确定。

在 CentOS 上这个值等于 5。

一旦收到客户端的 ACK,服务端就开始尝试把它加入另外一个全连接队列(Accept Queue)。

全连接队列

「全连接队列」包含了服务端所有完成了三次握手,但是还未被应用调用 accept 取走的连接队列。

此时的 socket 处于 ESTABLISHED 状态。每次应用调用 accept() 函数会移除队列头的连接。如果队列为空,accept() 通常会阻塞。全连接队列也被称为?Accept 队列

你可以把这个过程想象生产者、消费者模型:

内核是一个负责三次握手的生产者,握手完的连接会放入一个队列。

我们的应用程序是一个消费者,取走队列中的连接进行下一步的处理。

这种生产者消费者的模式,在生产过快、消费过慢的情况下就会出现队列积压。

listen 函数的第二个参数 backlog 用来设置全连接队列大小,但不一定就会选用这一个 backlog 值,还受限于 somaxconn,等下会有更详细的内容说明全连接队列大小的计算规则。

int listen(int sockfd, int backlog)

如果全连接队列满,内核会舍弃掉 client 发过来的 ack(应用层会认为此时连接还未完全建立)。

ss 命令可以查看全连接队列的大小和当前等待 accept 的连接个数,执行?ss -lnt?即可。

对于?LISTEN 状态的套接字,Recv-Q 表示 accept 队列排队的连接个数Send-Q 表示全连接队列(也就是 accept 队列)的总大小。

套接字信息

ifconfig 和 ip 只显示了网络接口收发数据包的统计信息,但在实际的性能问题中,网络协议栈中的统计信息,我们也必须关注。你可以用 netstat 或者 ss ,来查看套接字、网络栈、网络接口以及路由表的信息。

我个人更推荐,使用 ss 来查询网络的连接信息,因为它比 netstat 提供了更好的性能(速度更快)。

比如,你可以执行下面的命令,查询套接字信息:

netstat 和 ss 的输出也是类似的,都展示了套接字的状态、接收队列、发送队列、本地地址、远端地址、进程 PID 和进程名称等。

其中,接收队列(Recv-Q)和发送队列(Send-Q)需要你特别关注,它们通常应该是 0。

当你发现它们不是 0 时,说明有网络包的堆积发生。

当然还要注意,在不同套接字状态下,它们的含义不同:

syn backlog 是 TCP 协议栈中的半连接队列(sync queue)长度,相应的也有一个全连接队列(accept queue),它们都是维护 TCP 状态的重要机制。

顾名思义,所谓半连接,就是还没有完成 TCP 三次握手的连接,连接只进行了一半,而服务器收到了客户端的 SYN 包后,就会把这个连接放到半连接队列中,然后再向客户端发送 SYN+ACK 包。而全连接,则是指服务器收到了客户端的 ACK,完成了 TCP 三次握手,然后就会把这个连接挪到全连接队列中。这些全连接中的套接字,还需要再被 accept() 系统调用取走,这样,服务器就可以开始真正处理客户端的请求了。?

参考

TCP 三次握手原理,你真的理解吗?

https://mp.weixin.qq.com/s/yH3PzGEFopbpA-jw4MythQ

TCP SOCKET中backlog参数的用途是什么?

http://www.cnxct.com/something-about-phpfpm-s-backlog/

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 11:18:35  更:2022-01-24 11:21:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:19:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码