从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之间的联系

d7ec6d8ba28d40639225583d2a6c7073.png


接下来开始我们真正的问题讨论: 

二、 当通信双方中的一方如客户端主动断开连接时,仅是在客户端的视角下连接已经断开,在服务端的眼中,连接依然存在,为什么?——触发EPOLLRDHUP事件:对端关闭连接或停止写操作

套接字通信是全双工的,这意味着服务端和客户端之间可以同时进行通信,而要使得两者之间通信所传输的数据互不干扰,这就要求要为通信提供两个缓冲区,一个用来存储接收的数据,一个用于存储需要发送的数据。TCP为每个连接提供了两个独立的缓冲区:接收缓冲区和发送缓冲区。而客户端与服务端之间建立连接的实质就是通信双方是否能正常进行通信——即1、客户端是否能向服务端发送信息;2、服务端能否接收到客户端所发送的信息并且能否能否向客户端发送信息;3、客户端能否接收到服务端发送的信息。

4574c40f33e243eeac87f3af5b557398.png

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

ab23c21afeb74e4d894e0b577503b4ea.png

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

8e1dc926724643f4925ca18fa474304c.png

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

250d802493454ce690fb244b21f3144c.png


 三、EPOLLIN:可读事件 和 EPOLLOUT:可写事件 的触发时机,什么时候设置读事件关心?什么时候设置写事件关心?

epoll所要做的就是等待资源就绪。

对于一条连接而言,在连接成功建立之初,我们就应对其设置读事件关心。——因为通信中的一方始终需要接收另一方发送的信息,继而要去对信息进行处理。这就需要我们调用read/recv等读取函数去读取接收缓冲区中的内容。但,缓冲区中如果没有数据,我们调用读取函数就会阻塞(BLOCK模式,连接关闭时返回0)或者读取失败(NONBLOCK模式,错误码为EAGAIN 或 EWOULDBLOCK,表示资源暂时不可用,连接关闭时返回0)。

那么读就绪的条件就是:在LT模式下,接收缓冲区中有数据即为读就绪。在ET模式下,接收缓冲区中接收到新数据即为读就绪。

类似的,写事件的就绪:在LT模式下,发送缓冲区中有空间即为写就绪。在ET模式下,发送缓冲区中有新空间即为写就绪。

但是,我们并不能在连接成功建立之初对其设置写事件关心!连接建立之初,发送缓冲区中一定是有空间的,因为此时我们并未将数据处理的结果写入到发送缓冲区中。如果此时设置了写事件关心,那么写事件是常就绪的,然而我们大多数的事件可能是在进行读取数据与业务处理,并不一定需要发送数据。同时,不必要的写事件常就绪还会造成epoll模型中红黑树和就绪队列资源的占用和不必要的资源浪费。

所以,我们要在需要写数据的时候将设置关心写事件——即当应用层处理完读取上来的请求数据并生成响应数据需要发送给另一方时,我们再将该连接描述符的写事件设置为关心。必要的,在数据发送完毕后,及时关闭对该连接的写事件关心。


四、EPOLLPRI:优先处理数据事件 —— 当TCP报文携带的是紧急数据时触发(URG = 1, 紧急指针有效)

8f27bc6477544904834e1026d48b532f.png

 当TCP报头中的保留位字段中的URG字段设置为1时,发送应用进程就告诉发送方的TCP有紧急数据要传送——该报文数据中包含紧急数据,于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据。这时URG需要搭配首部中的紧急指针字段配合使用。

当接收方的接收缓冲区根据TCP报头识别到该段报文的数据包含紧急数据时,会通知与其相关的系统调用,epoll会返回EPOLLPRI事件。说明有紧急数据到来,需要优先处理。

 

 

 

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

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

相关文章

使用RSyslog将Nginx Access Log写入Kafka

个人博客地址:使用RSyslog将Nginx Access Log写入Kafka | 一张假钞的真实世界 环境说明 CentOS Linux release 7.3.1611kafka_2.12-0.10.2.2nginx/1.12.2rsyslog-8.24.0-34.el7.x86_64.rpm 创建测试Topic $ ./kafka-topics.sh --zookeeper 192.168.72.25:2181/k…

使用 Docker 部署 Java 项目(通俗易懂)

目录 1、下载与配置 Docker 1.1 docker下载(这里使用的是Ubuntu,Centos命令可能有不同) 1.2 配置 Docker 代理对象 2、打包当前 Java 项目 3、进行编写 DockerFile,并将对应文件传输到 Linux 中 3.1 编写 dockerfile 文件 …

《研发管理 APQP 软件系统》——汽车电子行业的应用收益分析

全星研发管理 APQP 软件系统在汽车电子行业的应用收益分析 在汽车电子行业,技术革新迅猛,市场竞争激烈。《全星研发管理 APQP 软件系统》的应用,为企业带来了革命性的变化,诸多收益使其成为行业发展的关键驱动力。 《全星研发管理…

22、PyTorch nn.Conv2d卷积网络使用教程

文章目录 1. 卷积2. python 代码3. notes 1. 卷积 输入A张量为: A [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ] \begin{equation} A\begin{bmatrix} 0&1&2&3\\\\ 4&5&6&7\\\\ 8&9&10&11\\\\ 12&13&14&15 \end{b…

ASP.NET Core - 依赖注入(四)

ASP.NET Core - 依赖注入(四) 4. ASP.NET Core默认服务5. 依赖注入配置变形 4. ASP.NET Core默认服务 之前讲了中间件,实际上一个中间件要正常进行工作,通常需要许多的服务配合进行,而中间件中的服务自然也是通过 Ioc…

UE5游戏性能优化指南

解除帧率限制 启动游戏 按 “~” 键 输入 t.MaxFPS 200 可以解除默认帧率限制达到更高的帧率 UE游戏性能和场景优化思路: 1. 可以把可延展性调低,帧率会大幅提高,但画质会大幅降低 2.调整固定灯光,静态光源&#xff…

深度学习中的卷积和反卷积(四)——卷积和反卷积的梯度

本系列已完结,全部文章地址为: 深度学习中的卷积和反卷积(一)——卷积的介绍 深度学习中的卷积和反卷积(二)——反卷积的介绍 深度学习中的卷积和反卷积(三)——卷积和反卷积的计算 …

【C语言】线程

目录 1. 什么是线程 1.1概念 1.2 进程和线程的区别 1.3 线程资源 2. 函数接口 2.1创建线程: pthread_create 2.2 退出线程: pthread_exit 2.3 回收线程资源 练习 1. 什么是线程 1.1概念 线程是一个轻量级的进程,为了提高系统的性能引入线程。 在同一个进…

【C语言】字符串函数详解

文章目录 Ⅰ. strcpy -- 字符串拷贝1、函数介绍2、模拟实现 Ⅱ. strcat -- 字符串追加1、函数介绍2、模拟实现 Ⅲ. strcmp -- 字符串比较1、函数介绍2、模拟实现 Ⅳ. strncpy、strncat、strncmp -- 可限制操作长度Ⅴ. strlen -- 求字符串长度1、函数介绍2、模拟实现&#xff08…

Windows部署NVM并下载多版本Node.js的方法(含删除原有Node的方法)

本文介绍在Windows电脑中,下载、部署NVM(node.js version management)环境,并基于其安装不同版本的Node.js的方法。 在之前的文章Windows系统下载、部署Node.js与npm环境的方法(https://blog.csdn.net/zhebushibiaoshi…

centos 8 中安装Docker

注:本次样式安装使用的是centos8 操作系统。 1、镜像下载 具体的镜像下载地址各位可以去官网下载,选择适合你们的下载即可! 1、CentOS官方下载地址:https://vault.centos.org/ 2、阿里云开源镜像站下载:centos安装包…

STM32-笔记40-BKP(备份寄存器)

一、什么是BKP(备份寄存器)? 备份寄存器是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒,或…

vue-cli项目配置使用unocss

在了解使用了Unocss后&#xff0c;就完全被它迷住了。接手过的所有项目都配置使用了它&#xff0c;包括一些旧项目&#xff0c;也跟同事分享了使用Unocss的便捷性。 这里分享一下旧项目如何配置和使用Unocss的&#xff0c;项目是vue2vue-cli构建的&#xff0c;node<20平常开…

新增文章分类功能

总说 过程参考黑马程序员SpringBoot3Vue3全套视频教程&#xff0c;springbootvue企业级全栈开发从基础、实战到面试一套通关_哔哩哔哩_bilibili 目录 总说 一、功能实现 1.1 Controller层 1.2 Service层 1.3 Impl层 1.4 Mapper层 1.5 测试接口 二、优化 2.1 2.2 一、…

知识图谱常见的主流图数据库

在知识图谱中&#xff0c;主流使用的图数据库包括以下几种&#xff1a; Neo4j&#xff1a;这是目前全球部署最广泛的图数据库之一&#xff0c;具有强大的查询性能和灵活的数据模型&#xff0c;适用于复杂关系数据的存储和查询。 JanusGraph&#xff1a;JanusGraph是一个开源的…

JavaSE学习心得(多线程与网络编程篇)

多线程-网络编程 前言 多线程&JUC 多线程三种实现方式 第一种实现方式 第二种实现方式 第三种实现方式 常见成员方法 买票引发的安全问题 同步代码块 同步方法 Lock锁 生产者和消费者 常见方法 等待唤醒机制 练习 抢红包 抽奖 多线程统计并求最…

Pytorch基础教程:从零实现手写数字分类

文章目录 1.Pytorch简介2.理解tensor2.1 一维矩阵2.2 二维矩阵2.3 三维矩阵 3.创建tensor3.1 你可以直接从一个Python列表或NumPy数组创建一个tensor&#xff1a;3.2 创建特定形状的tensor3.3 创建三维tensor3.4 使用随机数填充tensor3.5 指定tensor的数据类型 4.tensor基本运算…

candb++ windows11运行报错,找不到mfc140.dll

解决问题记录 mfc140.dll下载 注意&#xff1a;放置位置别搞错了

​公专网一体5G工业路由器,智慧电网全链路加密监控管理

随着可再生能源的集成 电网调度策略复杂性增加 需更精细的并网管理以平衡供需 传统电力网络的通信基础落后 难以适应电力设施的广泛分布 和日益增长的管理维护需求 计讯物联5G公专网一体路由器 通过融合公网和专网的优势 有效解决了现代电网对于 高效、灵活和安全通信的需求 ↓…

【Linux】--- 进程的等待与替换

进程的等待与替换 一、进程等待1、进程等待的必要性2、获取子进程status3、进程等待的方法&#xff08;1&#xff09;wait&#xff08;&#xff09;函数&#xff08;2&#xff09;waitpid函数 4、多进程创建以及等待的代码模型5、非阻塞接口 轮询 二、进程替换1、替换原理2、替…