从epoll事件的视角探讨TCP:三次握手、四次挥手、应用层与传输层之间的联系
目录
一、应用层与TCP之间的联系
二、 当通信双方中的一方如客户端主动断开连接时,仅是在客户端的视角下连接已经断开,在服务端的眼中,连接依然存在,为什么?——触发EPOLLRDHUP事件:对端关闭连接或停止写操作
三、EPOLLIN:可读事件 和 EPOLLOUT:可写事件 的触发时机,什么时候设置读事件关心?什么时候设置写事件关心?
四、EPOLLPRI:优先处理数据事件 —— 当TCP报文携带的是紧急数据时触发(URG = 1, 紧急指针有效)
我们来回顾使用epoll的流程:
1、首先,创建监听套接字,将其设置为读事件关心并挂载到epoll的红黑树中。监听套接字读取事件就绪的条件是:TCP全连接队列不为空,在LT模式下,只要全连接队列中有数据就满足读时间就绪;在ET模式下,只有当全连接队列中有新连接到来时,才会触发一次读时间就绪。
2、当触发监听套接字读时间就绪后,使用epoll_wait从epoll模型的就绪队列中将就绪事件及其对应的套接字提取出来,根据套接字类型的不同和就绪事件的不同进而执行不同的回调函数。对于listen套接字而言,当读事件就绪后,它需要调用accept从TCP全连接队列中获取新连接的文件描述符。并将其挂载到epoll中,设置读事件关心。
3、当该连接接收到请求数据后,进行业务处理——根据请求构建响应数据放入该连接的用户级缓冲区中,并设置该连接的文件描述符为写事件关心,等待写事件的就绪。当epoll_wait获取到该连接的写事件就绪后再去执行写事件对应的回调函数。当写入完成后,需要关闭该连接的对写事件的关心。
4、当客户端主动关闭连接时,服务端需要先将连接接收缓冲区中的请求数据处理完毕,并且将数据处理的结果返回给客户端(这样做是出于逻辑的完善,具体情况看要看具体是怎样设计的)。当服务端发现客户端已经主动断开连接后,服务端也要断开连接,并清除文件描述符和移除epoll中对该文件描述符的关心,以及其他相关的资源。
在应用层中,当调用close函数关闭套接字文件描述符时视为发起断开连接。
一、应用层与TCP之间的联系

接下来开始我们真正的问题讨论:
二、 当通信双方中的一方如客户端主动断开连接时,仅是在客户端的视角下连接已经断开,在服务端的眼中,连接依然存在,为什么?——触发EPOLLRDHUP事件:对端关闭连接或停止写操作
套接字通信是全双工的,这意味着服务端和客户端之间可以同时进行通信,而要使得两者之间通信所传输的数据互不干扰,这就要求要为通信提供两个缓冲区,一个用来存储接收的数据,一个用于存储需要发送的数据。TCP为每个连接提供了两个独立的缓冲区:接收缓冲区和发送缓冲区。而客户端与服务端之间建立连接的实质就是通信双方是否能正常进行通信——即1、客户端是否能向服务端发送信息;2、服务端能否接收到客户端所发送的信息并且能否能否向客户端发送信息;3、客户端能否接收到服务端发送的信息。

以上过程实质上就是三次握手的验证过程,进行三次握手的目的就是验证通信双方是否具备通信的能力,即双方是否能够正常接收数据和发送数据。可见,客户端与服务端之间连接的建立实质上就是两者发送缓冲区与接收缓冲区之间的联系。

当客户端主动调用close关闭连接时,实际上仅仅是客户端的发送缓冲区到服务端的接收缓冲区这条路线被切断了。对服务端而言,服务端的发送缓冲区到客户端的接收缓冲区之间的联系依旧存在。

所以,当客户端主动关闭连接时,我们需要及时调用read等函数将服务端接收缓冲区中的剩余数据读取至应用层并进行处理。数据处理完成后,如果有需要,可以继续发送给客户端。在数据清理完成后,服务端需要清理与该连接相关的资源。

三、EPOLLIN:可读事件 和 EPOLLOUT:可写事件 的触发时机,什么时候设置读事件关心?什么时候设置写事件关心?
epoll所要做的就是等待资源就绪。
对于一条连接而言,在连接成功建立之初,我们就应对其设置读事件关心。——因为通信中的一方始终需要接收另一方发送的信息,继而要去对信息进行处理。这就需要我们调用read/recv等读取函数去读取接收缓冲区中的内容。但,缓冲区中如果没有数据,我们调用读取函数就会阻塞(BLOCK模式,连接关闭时返回0)或者读取失败(NONBLOCK模式,错误码为EAGAIN 或 EWOULDBLOCK,表示资源暂时不可用,连接关闭时返回0)。
那么读就绪的条件就是:在LT模式下,接收缓冲区中有数据即为读就绪。在ET模式下,接收缓冲区中接收到新数据即为读就绪。
类似的,写事件的就绪:在LT模式下,发送缓冲区中有空间即为写就绪。在ET模式下,发送缓冲区中有新空间即为写就绪。
但是,我们并不能在连接成功建立之初对其设置写事件关心!连接建立之初,发送缓冲区中一定是有空间的,因为此时我们并未将数据处理的结果写入到发送缓冲区中。如果此时设置了写事件关心,那么写事件是常就绪的,然而我们大多数的事件可能是在进行读取数据与业务处理,并不一定需要发送数据。同时,不必要的写事件常就绪还会造成epoll模型中红黑树和就绪队列资源的占用和不必要的资源浪费。
所以,我们要在需要写数据的时候将设置关心写事件——即当应用层处理完读取上来的请求数据并生成响应数据需要发送给另一方时,我们再将该连接描述符的写事件设置为关心。必要的,在数据发送完毕后,及时关闭对该连接的写事件关心。
四、EPOLLPRI:优先处理数据事件 —— 当TCP报文携带的是紧急数据时触发(URG = 1, 紧急指针有效)

当TCP报头中的保留位字段中的URG字段设置为1时,发送应用进程就告诉发送方的TCP有紧急数据要传送——该报文数据中包含紧急数据,于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据。这时URG需要搭配首部中的紧急指针字段配合使用。
当接收方的接收缓冲区根据TCP报头识别到该段报文的数据包含紧急数据时,会通知与其相关的系统调用,epoll会返回EPOLLPRI事件。说明有紧急数据到来,需要优先处理。
相关文章:
从epoll事件的视角探讨TCP:三次握手、四次挥手、应用层与传输层之间的联系
目录 一、应用层与TCP之间的联系 二、 当通信双方中的一方如客户端主动断开连接时,仅是在客户端的视角下连接已经断开,在服务端的眼中,连接依然存在,为什么?——触发EPOLLRDHUP事件:对端关闭连接或停止写…...
Redis复制(replica)
Redis主从复制 [Redis主从复制](replica)是一个多Redis实例进行数据同步的过程,其中一个实例是主实例(Master),其他实例是从实例(Slave)。主实例负责处理命令请求,而从实…...
[云讷科技] 用于软件验证的仿真环境
我们使用Pursuit自动驾驶仪为各种场景设计仿真环境,以便用户可以在模拟环境中直接验证他们的软件,无需现场测试。该环境基于Gazebo引擎。 1. 工作区目录 模拟环境的工作区位于提供的U盘中的~/pursuit_space/sitl_space_pursuit中。用户可以按照用户手册…...
使用 Vite 和 Vue 框架创建组件库
在前端开发中,组件化开发已成为一种高效、可维护的方式。通过创建组件库,不仅可以提高代码复用率,还能方便地在不同项目之间共享组件。本文将详细介绍如何使用 Vite 和 Vue 框架创建一个组件库,并将其导出供其他项目使用。为保持一…...
【数据结构学习笔记】19:跳表(Skip List)
介绍 跳表是一个能在 O ( n l o g n ) O(nlogn) O(nlogn)时间完成查找、插入、删除的数据结构,相比于树形结构优点就是很好写(所以也用于实现Redis ZSet)。其核心思想就是维护一个元素有序的,能随机提升索引层数的链表。最下面一…...
【8】深入理解 Go 语言中的协程-从基础到高级应用
文章目录 一、引言 🌟二、协程基础概念 🧐(一)什么是协程(二)协程与线程、进程的区别三、协程的创建与启动 🚀(一)使用 go 关键字创建协程(二)简单…...
深入理解 ECMAScript 2024 新特性:字符串 isWellFormed 方法
ECMAScript 2024 引入了一个新的字符串实例方法:String.prototype.isWellFormed。这一新增功能是为了帮助开发者更容易地验证字符串是否为有效的 Unicode 文本。本文将详细介绍这一方法的使用场景、实现原理及其在实际应用中的价值。 String.prototype.isWellFormed…...
算法分析与设计之贪心算法
文章目录 前言一、Greedy Algorithms1.1 贪心选择性质1.2 最优子结构性质1.3 正确性证明 二、典型例题2.1 Interval Scheduling间隔调度2.2 Interval Partitioning最少间教室排课2.3 Selecting Breakpoints选择加油站停靠点2.4 硬币找零2.5 Scheduling to Minimizing Lateness2…...
Centos 宝塔安装
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 安装成功界面 宝塔说明文档 https://www.bt.cn/admin/servers#wcu 或者可以注册宝塔账号 1 快速部署 安装docker 之后 2 需要在usr/bin下下载do…...
蓝桥与力扣刷题(709 转换成小写字母)
题目:给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。 示例 1: 输入:s "Hello" 输出:"hello"示例 2: 输入:s "here…...
Redis的过期策略、内存淘汰机制
Redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的?还有,你的数据已经设置了过期时间,但是时间到了,为什么内存占用率还是比较高? 一、Redis的过期策略 Redis采用的是定期删除惰性删除策略。 1…...
视觉多模态大模型---MiniMax-vl-01---以闪电般的注意力缩放基础模型
简介 MiniMax-VL-01 是与今年1月15日由上海稀宇科技有限公司(MiniMax)发布并开源的一款视觉多模态大模型,它与基础语言大模型 MiniMax-Text-01 一同构成了 MiniMax-01 系列。这款模型的设计初衷是为了应对日益增长的长上下文处理需求&#x…...
【微服务】面试 3、 服务监控 SkyWalking
微服务监控的原因 问题定位:在微服务架构中,客户端(如 PC 端、APP 端、小程序等)请求后台服务需经过网关再路由到各个微服务,服务间可能存在多链路调用。当某一微服务挂掉时,在复杂的调用链路中难以迅速确定…...
【案例81】NMC调用导致数据库的效率问题
问题现象 客户在使用NC系统时,发现系统特别卡顿。需要紧急排查。 问题分析 排查NMC发现,所有的线程都处于执行SQL层面,说明数据库当前出现了异常。查看数据库资源状态发现,Oracle相关进程CPU利用率达到了100%。 查看现在数据库…...
Linux_信号
信号的概念 && 知识补充 信号是进程之间事件异步通知的一种方式,是一种软中断。 标准信号:编号为1-31之间都是标准信号,这些都是预定义信号,用于通知进程发生的各种事件。实时信号:编号从32开始起均是实时信号…...
LeetCode100之搜索二维矩阵(46)--Java
1.问题描述 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回…...
学员答疑:安卓分屏窗口的TouchableRegion设置流程追踪
背景: vip学员在群里问到了一个分屏触摸区域设置的问题,开始以为就是和普通Activity设置区域没啥差别,都是在InputMonitor中进行的设置,但是仔细研究下来其实并不是哈。本文就带大家来手把手分析一下分屏情况下的触摸区域是怎么设置的。 d…...
[cg] UE5 调试技巧
UE 中 rhi命令的提交是在render 线程,而graphics api 真正的执行是在rhi 线程, 今天想看下rhi的底层调用,但由于是通过task执行的,无法获取到render thread传入的地方,调试起来不太方便。 可通过开启下面的命令来调试 …...
Python Wi-Fi密码测试工具
Python Wi-Fi测试工具 相关资源文件已经打包成EXE文件,可双击直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢,点…...
Linux 创建用户
Linux 创建用户 创建用户 sudo useradd -m -s /bin/bash test - -m:自动创建家目录 /home/test - -s /bin/bash:指定默认的 shell 为 bash修改密码 # 修改密码 sudo passwd test删除用户 userdel -r zengshun - -r:把用户的主目录一起删…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
