TCP全连接队列和tcpdump抓包

news2024/11/23 15:48:15

全连接队列

listen第二个参数

服务器在调用listen的时候,listen的第二个参数  + 1,就是TCP全连接队列的长度。

当客户端的连接进入established 状态后,如果服务器没有调用accept将连接取走,那么该连接就会待在TCP全连接队列中,直到上层调用accept将其取走。

 在全连接队列中的连接可以维持很长一段时间,除非上层调用accep取走,或者被上层主动关闭了;如果全连接队列满了,那么新来的链接就无法进入established状态,OS也会为这种状态的连接建立一种临时的数据结构,这个数据结构里的很多字段都未初始化完,会被OS保存在半连接队列中,在半连接队列中的连接保存时间一般比较短,一般是半分钟到一分钟。

为什么要有全连接队列?

当服务器很忙的时候,来不及调用accept接口,那么此时新连接就会被放在全连接队列当中,当服务器空闲下来时,就可以直接将全连接队列中的连接取走,然后进行业务处理。如果没有全连接队列,那么当服务器突然空闲下来的时候,这时候突然又没有连接来访问了,这就导致服务器的对资源的利用效率降低,吞吐量降低。会增加服务器的闲置率,减少给用户提供服务的效率和体验。

那全连接队列很长可以吗?

当然不可以。假设一个新来的用户一过来就在全连接末尾排队,说明此时的服务器压力已经很大了。如果这个队列很长,为了维护这个队列占用了大把的内存空间,服务器的处理速度慢,用户还要排很长时间,那为什么不让这个队列长度短一点,把节省下来的内存空间给服务器进行运算呢?

这个全连接的本质其实就是生产者消费者模型。服务器相当于消费者,负责处理连接,客户端相当于生产者,创造连接,并且将连接放入到缓冲区,也就是全连接队列中。

总结:

  全连接队列本质上就是当服务器压力太大的时候,OS会在底层会为服务器将来不及处理的连接维护起来,等服务器空闲的时候再把连接获取上去。其中队列的长度就是listen的第二个参数 back_log + 1。 

从内核层面理解socket和连接

连接的本质也是一种数据结构。 

服务器也是一个进程,它有一个自己的task_struct 结构体,内部有一个自己的文件描述符表 struct files_struct 里面有一个 struct file* fd_array[] 文件描述符数组。

并且在进程启动的时候,OS会默认给我们打开 标准输入,标准输出,标准错误输出,分别占了 0,1,2三个文件描述符。在这里,当我们创建listen套接字的时候,会给用户返回3号这个文件描述符。既然它有文件描述符,那么也有自己的struct file结构体。

以上是文件系统部分。当我们创建socket套接字的时候,内核会帮我们创建一个 struct socket结构体。

我们发现这里面包含了一个回指向struct file结构体的指针

 另外在struct file结构体中也包含了如下字段

void* private_data。

 在创建套接字的时候,这个void* private_data会指向struct socket,于是它俩之间就关联起来了!

对于struct socket结构体,我们可以理解它是网络socket的入口。 为什么这么说呢,我们再来详细说明一下struct socket内部的一些字段。

 

 const struct proto_ops* 这是一个指针,里面包含了一组方法簇。

所以上层在读写套接字时,就使用这里面的函数指针调用不同的方法。 

当我们创建TCP套接字的时候,OS会在底层为用户创建一个struct tcp_sock

 这就是在三次握手完成以后,OS会在内核给连接创建一个数据结构,就是它。

仔细留意这个结构体的第一个成员 ,又是一个结构体,类型是 inet_connection_sock。示意图:

 在inet_connection_sock结构体中包含了很多跟tcp连接相关的信息,如下:

并且在这里面 

struct request_sock_queue就是管理TCP全连接队列的。 

 但是我们又发现了它的第一个成员还是一个结构体

也就是struct inet_sock。 看一下它里面长啥样,inet_sock意思也就是网络套接字的意思。

 所以我们看到了很多跟网络相关的字段,比如端口号,ip等。示意图又多了一层

 但是又发现这个结构体居然还嵌套了一个结构体

也就是 struct sock 。所以示意图再加一层

 但是这个结构体是不是很眼熟?没错,这就是一开始在 struct socket结构体里面,有一个指向它的指针:

 struct sock结构体:

 这里面包含的更多的是一些报文的信息。其中里面还包含了两个很重要的字段

它俩就是接收和发送缓冲区。

这里面也有指针

 再回到刚刚,所以只要OS创建了一个 tcp_sock

那么刚刚嵌套的那些结构体自然也就都有了。并且我们注意到,这些嵌套的结构体都是上一层的第一个字段,也就意味着可以直接用指针来进行访问! 需要访问哪一个结构体内部的字段,只需要对这个指针进行相应的强转即可。这其实也就是C风格的多态。

另外UDP也有自己的套接字

它的第一个字段也是一个结构体,但是与TCP不一样的是,它的一个字段的结构体直接就是 inet_sock,也就是网络相关的套接字。因为UDP的实现比TCP简单,它不需要连接队列什么的,所以它不需要那么多字段。 

所以相比之下,UDP不需要再嵌套 inet_connection_sock这个结构体。

同理

 struct sock* 经过强转,同样也可以指向udp_sock。

它们的方法集也会变得不同。

在struct socket里面还有一个 type字段,就可以标识这是一个tcp还是一个udp套接字。

这样一看,struct socket可以看作基类,tcp_sock 和udp_sock可以看作是子类。

所以struct socket也成为 BSD socket 也就是通用网络接口。

学到这里其实可以在系统层面上给网络进行分层,

struct file属于第一层 :虚拟文件层。未来所有的套接字都可以变成文件。

struct socket 属于第二层:通用套接字层。

inet_sock 属于第三层:通用网络层,因为inet可以本地通信,所以不只有tcp和udp两种套接字。

struct inet_device 属于第四层: 网络设备层。跟网卡设备打交道的。(了解)

刚刚说的都是关于创建listen套接字的。

那么接收连接呢?

假设listen套接字的文件描述符是3,那么当三次握手成功之后,OS就会为新连接创建一个tcp_sock结构体,当然这个连接不用关系全连接队列的这些字段。创建好之后,就会把这个结构体放入到 3号文件的 全连接队列里。

当上层调用accept获取后,那么OS就会创建一个 struct file,和一个 struct socket,此时的文件描述符就是4,并将 struct socket 里面的 struct sock* 指向刚刚拿上来的 tcp_sock,这样也就关联起来了。那么以后就可以直接通过4号文件描述符,来对这个套接字进行读和写的操作了。 

补充:

在sk_buff里面,通过控制指针的移动来对报文进行解包,提取有效载荷。 

抓包

使用TCP dump抓包 

Ubuntu中,如果没有安装,可以先安装

sudo apt-get update
sudo apt-get install tcpdump

 常见使用:

sudo tcpdump -i any tcp
-i any 指定捕获所有网络接口上的数据包, tcp 指定捕获 TCP 协议的数据
包。 i 可以理解成为 interface 的意思

另外云服务和本地的抓包一般是不一样的。

ifconfig

lo就是本地环回。云服务器下网络通信用的就是eth0接口。 

指定特定源IP地址 && 特定目的IP地址

比如

sudo tcpdump src host 192.168.1.100 and dst host 192.168.1.200
and tcp

src host表示的是指定源IP地址,dst host表示的是指定目的IP地址。

指定端口号抓包

例如捕获端口号为80的包(访问80端口的包)

sudo tcpdump port 80 and tcp

 保存捕获的数据包到文件,例如:

sudo tcpdump -i eth0 port 80 -w data.pcap

将抓到的包保存在 data.pcap文件中。

另外使用 tcpdump 的时候,有些主机名会被云服务器解释成为随机的主机名,如果不 想要,就用  -n 选项

 三次握手的抓包示例(服务器端启动的抓包软件):

 一个包的标志位有一个 S,说明是对方发送了 SYN请求,接着服务器发送了 S. 说明了服务器发送了SYN + ACK。最后客户端发了 . ,说明是一个ACK,至此三次握手完成。并且注意一些细节,在第二个包 SYN + ACK的时候,注意到 ack是上一个 seq 的序列号 + 1,接着在第三个包客户端给服务器 ACK时,此时的 ack = 1,这次的ack不是说确认了序号1,它是被置为了1,而且没有携带自己的序号seq。

四次挥手的抓包示例:

这里看着好像只有三次挥手。其实是因为在服务器的代码逻辑中,客户端退了,服务器立马就关闭客户端的文件描述符了,所以在图中的第二个包,服务器发送给客户端的也是一个FIN + ACK,也就是捎带应答。

如果客户端关闭了,但是服务器还有数据要给客户端发送,然后再关闭,那么就会是正常的四次挥手,如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2130168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Edge浏览器设置夜间模式/深色模式

问题背景 普通白色背景感觉有点刺眼,想改成深色背景,但是默认的设置里面只能修改边框的颜色: 这里虽然设置界面和边框变成了黑色的,但是实际上打开网页还是白色的。 全局配置 在Edge浏览器打开edge://flags/,然后搜索D…

海垦集团养殖场分布式光伏发电项目中的案例分享

1客户需求 海南农垦集团,原海南省农垦总公司,是中央直属三大垦区之一。集团在海南有多个养殖场,包括红华养猪场、红华肉牛繁育场等,计划在这些养殖场的屋顶安装分布式光伏系统,用于自发自用和余电上网。红华养猪场和红…

基于ESP32S3的链接大语言模型对话模块

本实物模块从实物外观、模块组成、API申请及功能说明四部分来介绍这款基于ESP32S3的大语言模型对话模块。 1、实物外观 2、模块介绍 本硬件平台主要由三个模块组成,包括MAX9814录音模块、MAX98357音频功放模块和ESP32S3模块。如下图所示。 MAX9814录音模块&#…

mac 如何开启指定端口供外部访问?

前言 需要 mac 上开放指定端口,指定 ip 访问 解决 在 macOS 上开放一个端口,并指定只能特定的 IP 访问,可以使用 macOS 内置的 pfctl(Packet Filter)工具来实现。 1、 编辑 pf 配置文件: 打开 /etc/pf.conf 文件进行编辑。 可以使…

深度解读MySQL意向锁的工作原理机制与应用场景

意向锁 意向锁的概念 意向锁是InnoDB自动添加的一种锁,不需要用户去干预。 是数据库中的一种表级锁,一个事务要给一个资源加锁时,必须要先获取到对应类型的意向锁之后,才可以给这个资源加上自己想要的共享锁或者排他锁&#xff0…

【C++ 面试 - 新特性】每日 3 题(十一)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

电容器制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

在当今全球制造业的数字化转型浪潮中,电容器制造业作为电子元件的关键领域,正积极拥抱5G智能工厂与物联数字孪生平台技术,以推动生产效率的飞跃和产品质量的提升。这一创新模式不仅为电容器制造业注入了新的活力,也为整个制造业的…

植物三萜皂苷生物合成途径及调控机制研究进展-文献精读48

摘要 三萜皂苷(triterpenoids saponins)是由三萜皂苷元和一个或多个糖基和/或其他化学基团缩合而成的一系列结构多样的天然化合物[1], 主要分布在五加科、蝶形花科、石竹科、桔梗科、毛茛科、玄参科、葫芦科等植物中[2]. 植物中三萜皂苷常分布在特定的器官和组织, 如人参(Pana…

TypeScript中 unknown类型的变量值赋值给具体类型的变量

将unknown类型分配给string类型,但我就想给y 赋值,提供了几个方法 // unknown 是类型安全的any let x : unknown; x 1; x true; x sdfj;let y : string; // y x;//不能将unknown类型分配给string类型,但我就想给y 赋值 ,下方…

Matlab如何配置小波工具(Wavelet Toolbox)

1、发现问题 因为实验要使用小波工具函数,运行时报错如下: 查看对应文件夹发现没有小波工具(也可在控制台输入ver),检查是否有该工具,输入后回车返回如下: 2、下载工具包 没有这个工具就要去下…

信息安全数学基础(8)整数分解

前言 在信息安全数学基础中,整数分解是一个核心概念,它指的是将一个正整数表示为几个正整数的乘积的形式。虽然对于任何正整数,理论上都可以进行分解(除了1只能分解为1本身),但整数分解在密码学和信息安全中…

机器学习:逻辑回归--过采样

目录 前言 一、为什么使用过采样? 二、代码实现 1.完整代码 2.数据预处理 3.进行过采样 4.建立模型 5.绘制混淆矩阵 总结 前言 过采样(Oversampling)是指在数据处理或机器学习中,增加少数类样本的数量以平衡类别分布。常…

JMM 指令重排 volatile happens-before

在单线程程序中,操作系统会通过编译器优化重排序、指令级并行重排序、内存系统重排序三个步骤对源代码进行指令重排,提高代码执行的性能。 但是在多线程情况下,操作系统“盲目” 地进行指令重排可能会导致我们不想看到的问题,如经…

Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化

Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化 1. 引言 在Android开发中,视觉化设计与流程管理至关重要。虽然开发工具如Android Studio强大,但它并不适用于所有设计场景。Draw.io是一款免费的在线绘图工具&#xff…

黑马头条第八天实战(上)

D8 1)登录功能需求说明 用户根据用户名和密码登录密码需要手动加盐验证需要返回用户的token和用户信息 2)模块搭建思路步骤 2.1)模块作用 先捋一下之前搭模块干了啥 feign-api 远程调用 自媒体保存时调用远程客户端进行增加文章&#x…

UE5中使用UTexture2D进行纹理绘制

在UE中有时需要在CPU阶段操作像素,生成纹理贴图等,此时可以通过UTexture2D来进行处理,例子如下: 1.CPP部分 首先创建一个蓝图函数库,将UTexture2D的绘制逻辑封装成单个函数: .h: #include &…

文本转语音工具 ChatTTS 使用教程

文章目录 Part.I IntroductionPart.II 一键安装部署Chap.I 下载Chap.II 使用Chap.III 存在的问题 Part.III 手动部署Chap.I 快速使用Chap.II 开发教程 Reference Part.I Introduction ChatTTS (Chat Text To Speech) 是专门为对话场景设计的文本转语音模型,例如LLM…

arcgisPro添加属性域

1、创建一个面要素,结果如下: 2、在【内容】列表中,选中该要素,点击【数据】选项卡,如下: 3、点击【属性域】按钮,如下: 4、点击【新建域】 5、添加一行属性域,如 6、保存…

【生日视频制作】海底石碑雕刻AE模板修改文字软件生成器教程特效素材【AE模板】

生日视频制作教程海底石碑雕刻AE模板修改文字特效广告生成神器素材祝福玩法AE模板工程 AE模板套用改图文教程↓↓: 怎么如何做的【生日视频制作】海底石碑雕刻AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 下载AE模板 安装AE软件…

python 注册 Nacos

根据项目需要 将python服务也纳入Nacos 中进行统一管理,所以进行python Nacos 项目适配。 记录本此适配过程。 python 安装不在说明。 系统版本:Linux 5.4.18-87.76-generic KYLINOS SMP Thu Aug 31 09:05:44 UTC 2023 aarch64 aarch64 aarch64 GNU/L…