【Linux】从内核角度理解 TCP 的 全连接队列(以及什么是 TCP 抓包)

文章目录


概念引入

我们知道,TCP的三次握手是由TCP协议 自动处理的,建立连接的过程与用户是否进行accept无关accept()的作用主要是为当前连接创建一个套接字,用于进行后续的通信;

当服务器来不及进行accept时,底层的TCP listen sock依然允许建立三次握手,建立连接成功,但这个建立连接的数量是有限的:backlog + 1,这个长度就是全连接队列的长度


理解全连接队列

我们根据上图得出几个结论:

  1. 如图中所述:连接本质是内核中的一种结构体对象,当客户端向服务器发送连接请求时,会先进行三次握手,随后加入到全连接队列中去,如果此时服务器闲置,则会将全连接队列中的连接拿去一部分进行处理
  2. 全连接队列的最大值是Backlog+1,不代表服务器只能同时处理Backlog+1个请求每次服务器会一次处理n个请求(全连接队列拿取)
  3. 全连接队列既不能为空,也不能太长
    • 为空:增加服务的闲置率,减少给用户提供的效率
    • 太长:增加用户等待时间(如果全连接队列本就有连接,证明服务器已经来不及处理连接);且增加空间浪费(需要给每个客户端连接创建额外的空间)

内核方面理解

上面的图片基本揭示了当创建一个文件描述符后,是如何建立连接读取数据的

当创建文件描述符后,会经历以下过程:

  1. 创建 struct file

    • 当一个进程请求创建一个 socket 时,内核首先分配一个 struct file 结构体,这个结构体代表打开的文件或 socket,包含文件的类型、状态和指向实际数据的指针。
  2. 创建 struct socket

    • 接下来,内核会为该 socket 创建一个 struct socket 结构体。这个结构体包含了 socket 的相关信息,如协议类型(TCP、UDP等)和相关的操作函数指针。
  3. 创建 struct tcp_socket

    • 如果是 TCP socket,内核会在 struct socket 中创建一个 struct tcp_socket 结构体。这一结构体专门处理 TCP 协议的特定信息和操作。
  4. 创建 struct inet_connection_sock

    • struct tcp_socket 还包含一个 struct inet_connection_sock,它负责处理 TCP 连接的状态,包括全连接队列(accept queue)和半连接队列(syn queue)。
  5. 包含 struct sock

    • inet_connection_sock 中有一个 struct sock,这是网络协议栈的核心结构之一。struct sock 包含了许多关键信息,包括:
      • 读写缓冲区:用于存储接收到的数据和待发送的数据。
      • 状态信息:例如连接的状态(监听、已连接、关闭等)。

全连接队列与缓冲区

  • 全连接队列

    • 一旦 TCP 三次握手完成,连接会被加入到全连接队列中,这样服务器就可以处理这些连接。
  • 读写缓冲区

    • 当数据通过网络接收时,它会被存储在 struct sock 中的读缓冲区中,进程可以通过系统调用(如 recv)读取这些数据。
    • 类似地,待发送的数据会放入写缓冲区,直到发送完成。

Tcp抓包

方法

Linux下的TCP抓包可以使用TCPDumpTCPDump 是一款强大的网络分析工具, 主要用于捕获和分析网络上传输的数据包

  1. 捕获所有网络接口上的 TCP 报文

使用以下命令可以捕获所有网络接口上传输的 TCP 报文:

bash 复制代码
sudo tcpdump -i any tcp
  1. 捕获指定网络接口上的 TCP 报文

只想捕获某个特定网络接口上的 TCP 报文, 可以使用以下命令:

bash 复制代码
sudo tcpdump -i <interface> tcp

interface部分的网络接口可以通过ifconfig命令查看

  1. 捕获特定源或目的 IP 地址的 TCP 报文

使用 host 关键字可以指定源或目的 IP 地址。 例如:

  • 要捕获源 IP 地址为 192.168.0.8 的 TCP 报文, 可以使用以下命令:
bash 复制代码
sudo tcpdump src host 192.168.0.8 and tcp
  • 要捕获目的 IP 地址为 192.168.0.9 的 TCP 报文, 可以使用以下命令:
bash 复制代码
sudo tcpdump dst host 192.168.0.9 and tcp
  • 同时指定源和目的 IP 地址, 可以使用 and 关键字连接两个条件:
bash 复制代码
sudo tcpdump src host 192.168.0.8 and dst host 192.168.0.9 and tcp
  1. 捕获特定端口的 TCP 报文

使用 port 关键字可以指定端口号。 例如, 要捕获端口号为 80 的 TCP 报文(通常是 HTTP 请求):

bash 复制代码
sudo tcpdump port 80 and tcp
  1. 保存捕获的数据包到文件

使用 -w 选项可以将捕获的数据包保存到文件中, 以便后续分析。 例如:

bash 复制代码
sudo tcpdump -i eth0 port 80 -w data.pcap

这个代码会把捕获到的 HTTP 流量保存到 data.pcap 文件中;

另外,pcap 后缀的文件与 PCAP(Packet Capture) 文件格式相关,即用于捕获网络数据包的文件格式

  1. 从文件中读取数据包进行分析

使用 -r 选项可以从文件中读取数据包进行分析:

bash 复制代码
tcpdump -r data.pcap

该代码将读取 data.pcap 文件中的数据包并进行分析

注意事项

  • 使用 tcpdump 时, 需要确保有足够的权限来捕获网络接口上的数据包。
  • 使用 tcpdump 的时候, 有些主机名会被云服务器解释成为随机的主机名, 可以使用 -n 选项避免

相关推荐
秋名山小桃子6 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉121387 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
岑梓铭14 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
努力学习的小廉14 分钟前
深入了解Linux —— make和makefile自动化构建工具
linux·服务器·自动化
MZWeiei18 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
7yewh33 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
Arenaschi37 分钟前
在Tomcat中部署应用时,如何通过域名访问而不加端口号
运维·服务器
小张认为的测试37 分钟前
Linux性能监控命令_nmon 安装与使用以及生成分析Excel图表
linux·服务器·测试工具·自动化·php·excel·压力测试
waicsdn_haha44 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
打鱼又晒网1 小时前
linux网络套接字 | 深度解析守护进程 | 实现tcp服务守护进程化
linux·网络协议·计算机网络·tcp