网络编程epoll和udp
# epoll模型核心要点 | |
## 1. epoll核心概念 | |
### 1.1 高效IO多路复用 | |
- 监视列表与激活列表分离 | |
- 内核使用红黑树存储描述符 | |
- 边缘触发模式(EPOLLET)支持 | |
### 1.2 事件触发机制 | |
- **水平触发(LT)**: | |
- 默认模式,类似select/poll | |
- 数据未读完持续触发事件 | |
- **边缘触发(ET)**: | |
- 需手动设置EPOLLET标志 | |
- 数据到达仅触发一次事件 | |
- 必须搭配非阻塞IO使用 | |
## 2. 关键操作函数 | |
### 2.1 epoll_create1 | |
```c | |
int epfd = epoll_create1(EPOLL_CLOEXEC); |
- 创建epoll实例
- EPOLL_CLOEXEC标志自动关闭文件描述符
2.2 epoll_ctl
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
- 操作类型:
- EPOLL_CTL_ADD 添加描述符
- EPOLL_CTL_MOD 修改事件
- EPOLL_CTL_DEL 删除描述符
- 事件结构体:
struct epoll_event {
uint32_t events; // EPOLLIN/EPOLLOUT/EPOLLERR
epoll_data_t data; // 携带用户数据
};
2.3 epoll_wait
int num = epoll_wait(epfd, events, maxevents, timeout);
- 阻塞等待事件触发
- 参数:
- timeout=-1永久阻塞
- timeout=0非阻塞
- 返回激活事件数量
3. 服务器实现流程
3.1 初始化阶段
// 创建TCP套接字 | |
int sfd = socket(AF_INET, SOCK_STREAM, 0); | |
// 绑定地址 | |
bind(sfd, (struct sockaddr*)&addr, sizeof(addr)); | |
// 设置监听队列 | |
listen(sfd, 5); | |
// 创建epoll实例 | |
int epfd = epoll_create1(EPOLL_CLOEXEC); |
3.2 事件处理循环
- 接受新连接:
int client_fd = accept(sfd, ...); | |
// 设置非阻塞模式 | |
fcntl(client_fd, F_SETFL, O_NONBLOCK); | |
// 添加至epoll监视 | |
epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &event); |
- 处理数据接收:
while(recv() > 0) { // 边缘触发需循环读取 | |
printf("Received: %s", buf); | |
if(errno == EAGAIN) break; // 非阻塞模式退出条件 | |
} |
- 异常处理:
if(ret == 0) { // 客户端关闭 | |
epoll_ctl(epfd, EPOLL_CTL_DEL, fd_temp, NULL); | |
close(fd_temp); | |
} |
4. 模型对比
特性 | select | poll | epoll |
---|---|---|---|
数据结构 | 位图(1024限制) | 结构体数组 | 红黑树 |
时间复杂度 | O(n)线性扫描 | O(n)线性扫描 | O(1)回调通知 |
触发模式 | 仅水平触发 | 仅水平触发 | 支持边缘触发 |
内存拷贝 | 每次全量复制 | 每次全量复制 | 增量操作 |
适用场景 | 低并发/跨平台 | 中等并发 | 高并发/Linux专用 |
5. 客户端实现要点
5.1 非阻塞IO设置
int flags = fcntl(fd, F_GETFL); | |
fcntl(fd, F_SETFL, flags | O_NONBLOCK); |
5.2 数据发送处理
while(1) { | |
fgets(buf, sizeof(buf), stdin); | |
send(sfd, buf, strlen(buf), 0); // 边缘触发需保证完全发送 | |
if(errno == EAGAIN) usleep(1000); // 流量控制 | |
} |
6. 特殊场景处理
6.1 多客户端通信
- 服务端维护客户端映射表
- 使用epoll_data携带会话上下文
event.data.ptr = &client_ctx; // 传递自定义数据结构
6.2 心跳检测机制
- 定时器队列管理连接状态
- EPOLLERR事件处理异常断开
# UDP套接字通信核心要点 | |
## 1. UDP协议特性 | |
### 基础特征 | |
- 无连接不可靠传输 | |
- 数据报独立发送 | |
- 支持数据顺序错乱 | |
- 效率高延迟低 | |
### 适用场景 | |
- 实时音视频传输 | |
- 在线游戏数据交互 | |
- 广播/组播通信 | |
## 2. 核心函数解析 | |
### socket创建 | |
```c | |
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); |
- 协议族必须为AF_INET
- 类型指定SOCK_DGRAM
数据接收
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, | |
struct sockaddr *src_addr, socklen_t *addrlen); |
- 获取发送方地址信息
- flags支持阻塞/非阻塞模式
数据发送
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, | |
const struct sockaddr *dest_addr, socklen_t addrlen); |
- 必须指定目标地址
- 单次发送上限4096字节
connect特殊用法
- 内核预存目标地址信息
- 允许使用send/recv简化调用
- 可多次调用更改目标地址
3. 服务器实现流程
核心步骤
- 创建DGRAM类型套接字
- 绑定固定IP和端口
- 循环接收客户端消息
- 响应消息附加处理标识
关键代码段
struct sockaddr_in cliaddr; | |
socklen_t len = sizeof(cliaddr); | |
ret = recvfrom(sockfd, buf, sizeof(buf), 0, | |
(struct sockaddr*)&cliaddr, &len); | |
sendto(sockfd, modified_buf, strlen(modified_buf), 0, | |
(struct sockaddr*)&cliaddr, len); |
4. 客户端实现模式
基础版本
- 每次发送指定目标地址
- 内核自动管理地址缓存
高效版本
connect(sockfd, (struct sockaddr*)&seraddr, sizeof(seraddr)); | |
send(sockfd, buf, strlen(buf), 0); |
- 内核持续存储目标地址
- 减少地址解析开销
5. 特殊处理机制
地址重置
struct sockaddr_in unspec = { .sin_family = AF_UNSPEC }; | |
connect(sockfd, (struct sockaddr*)&unspec, sizeof(unspec)); |
- 清除内核缓存的地址
- 恢复原始发送模式
错误检测
- recvfrom返回0表示空数据包
- errno==EAGAIN时处理非阻塞状态
- 发送失败需重试或记录日志
6. 与TCP对比差异
特性 | UDP | TCP |
---|---|---|
连接方式 | 无连接 | 三次握手建立连接 |
数据边界 | 保留报文边界 | 字节流形式 |
可靠性 | 不保证数据完整 | 可靠传输 |
资源消耗 | 低 | 高 |
适用场景 | 实时性要求高的场景 | 数据完整性场景 |
7. 性能优化方向
- 使用连接式UDP减少系统调用
- 设置SO_RCVBUF/SO_SNDBUF
- 采用非阻塞IO+epoll多路复用
- 实现应用层重传机制
相关文章:

网络编程epoll和udp
# epoll模型核心要点## 1. epoll核心概念### 1.1 高效IO多路复用- 监视列表与激活列表分离- 内核使用红黑树存储描述符- 边缘触发模式(EPOLLET)支持### 1.2 事件触发机制- **水平触发(LT)**:- 默认模式,类似select/poll- 数据未读完持续触发事件- **边缘…...
elementUI如何动态增减表单项
设置prop的字段::prop"configs.${i}.platform" <template><el-dialogtitle"编辑配置":close-on-click-modal"false":before-close"beforeClose":visible.sync"visible"v-if"visible"class&q…...

【iOS】源码阅读(四)——isa与类关联的原理
文章目录 前言OC对象本质探索clang探索对象本质objc_setProperty源码探索 cls与类的关联原理为什么说bits与cls为互斥关系isa的类型isa_t原理探索isa与类的关联 总结 前言 本篇文章主要是笔者在学习和理解类与isa的关联关系时所写的笔记。 OC对象本质探索 在学习和理解类与isa…...
sql server 2019 将单用户状态修改为多用户状态
记录两种将单用户状态修改为多用户状态,我曾经成功过的方法,供参考 第一种方法 USE master; GO -- 终止所有活动连接 DECLARE kill_connections NVARCHAR(MAX) ; SELECT kill_connections KILL CAST(session_id AS NVARCHAR(10)) ; FROM sys.dm_ex…...
uniapp引入七鱼客服微信小程序SDK
小程序引入七鱼sdk 1.微信公众平台引入2.代码引入3.在pagesQiyu.vue初始化企业appKey4.跳转打开七鱼客服 1.微信公众平台引入 账号设置->第三方设置->添加插件->搜索 QIYUSDK ->添加 2.代码引入 在分包中引入插件 "subPackages": [{"root":…...

uniapp 常用 UI 组件库
1. uView UI 特点: 组件丰富:提供覆盖按钮、表单、图标、表格、导航、图表等场景的内置组件。跨平台支持:兼容 App、H5、小程序等多端。高度可定制:支持主题定制,组件样式灵活。实用工具类:提供时间、数组操…...

SCI写作开挂!把Grammarly语法修订嵌入word
详细分享如何把Grammarly嵌入Word,实现英文写作时的实时语法校改。 ①进入Grammarly官网 ②点击右上角的“Get Grammarly Its free”会直接跳转到注册或者登录界面,如果还没有账号先注册。 ③注册或登录后进入这个页面,点击“Support”。 ④…...
PostgreSQL 配置设置函数
PostgreSQL 配置设置函数 PostgreSQL 提供了一组配置设置函数(Configuration Settings Functions),用于查询和修改数据库服务器的运行时配置参数。这些函数为数据库管理员提供了动态管理数据库配置的能力,无需重启数据库服务。 …...

2025年5月-信息系统项目管理师高级-软考高项-成本计算题
成本计算题挣值分析、成本计算题如何学?1、PV,EV,AC需要理解,根据题目给出的一些个条件需要求得这些值;2、CV,SV,CPI,SPI公式必须记住,需要根据求得的值判断项目的进度和成本的执行情况&#x…...
力扣-236.二叉树的最近公共祖先
题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以…...
Go 中闭包的常见使用场景
在 Go 中,闭包(Closure) 是一个函数值,它引用了其定义时所在作用域中的变量。也就是说,闭包可以访问并修改外部作用域中的变量。 Go 中闭包的常见使用场景 ✅ 1. 封装状态(无须结构体) 闭包可…...

SpringBoot中的Lombok库
一)Lombok库简介 Lombok是一个Java库,通过注解的方式简化代码编写,减少样板代码。它能够自动生成getter、setter、构造函数、toString等方法,提升开发效率。Lombok只是一个编译阶段的库,因此不会影响程序的运行。 二…...
《Java 大视界——Java 大数据在智能电网分布式能源协同调度中的应用与挑战》
随着风电、光伏等分布式能源大规模接入电网,传统调度系统面临数据规模激增、响应延迟显著、多源异构数据融合困难等核心问题。本文聚焦Java生态下的大数据技术体系,深入探讨其在智能电网实时监测、负荷预测、资源优化配置等场景中的落地实践。通过分析Sp…...

AI中的MCP是什么?MCP的作用及未来方向预测 (使用go-zero 快速搭建MCP服务器)
AI是当下最热的风。在当今AI技术飞速发展的时代,AI的应用已经渗透到我们日常生活的方方面面。然而,随着AI系统的复杂性不断增加,如何让AI具备更强的自主性和灵活性成为了业界关注的焦点。这就引出了Model Context Protocol(MCP&am…...

mac安装cast
背景 pycharm本地运行脚本时提示cast没有安装 问题原因 脚本尝试调用cast命令(以太坊开发工具foundry中的子命令),但您的系统未安装该工具。 从日志可见,错误发生在通过sysutil.py执行shell命令时。 解决方案 方法1…...
conda更换清华源
1、概览 anaconda更换速度更快、更稳定的下载源,在linux环境测试通过。 2、conda源查看 在修改之前可以查看下现有conda源是什么,查看conda配置信息,如下: cat ~/.condarc 可以看到你的conda源,以我的conda源举例&am…...
[原创](现代Delphi 12指南):[macOS 64bit App开发]: 注意“回车换行“的跨平台使用.
[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...
管理Oracle Data Guard的最佳实践
Oracle Data Guard的中文名字叫数据卫士,顾名思义,它是生产库的一道保障。所以管理Data Guard是DBA的一项重要工作之一,管理Data Guard时主要有以下几个注意点需要引起重视。 备份库的归档日志积压 一般情况下,生产库的归档日志是…...

一个简单点的js的h5页面实现地铁快跑的小游戏
以下是一个简化版的"地铁快跑"小游戏H5页面实现。这个游戏包含基本的角色跳跃、障碍物生成和计分系统,使用Canvas绘图技术实现。 完整源码 登录后复制 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-…...
作业帮Java后台开发面试题及参考答案(下)
final、finally、finalize 的区别是什么? final、finally和finalize是 Java 中三个功能完全不同的关键字,容易混淆,需从作用域、语法规则和实际用途等方面深入区分。 final的作用 final用于修饰类、方法和变量,体现 “不可变” 特性: 修饰类:表示该类不能被继承,例如 J…...

Hugging Face 中 LeRobot 使用的入门指南
相关源文件 .github/ISSUE_TEMPLATE/bug-report.yml .github/PULL_REQUEST_TEMPLATE.md README.md examples/1_load_lerobot_dataset.py examples/2_evaluate_pretrained_policy.py examples/3_train_policy.py lerobot/scripts/eval.py lerobot/scripts/train.py 本页面提供 …...

零基础入门Hadoop:IntelliJ IDEA远程连接服务器中Hadoop运行WordCount
今天我们来聊一聊大数据,作为一个Hadoop的新手,我也并不敢深入探讨复杂的底层原理。因此,这篇文章的重点更多是从实际操作和入门实践的角度出发,带领大家一起了解大数据应用的基本过程。我们将通过一个经典的案例——WordCounter&…...

HTML-3.3 表格布局(学校官网简易布局实例)
本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 系列文章目录 HTML-1.1 文本字体样式-字体设置、分割线、段落标签、段内回车以及特殊符号 HTML…...
Maven构建流程详解:如何正确管理微服务间的依赖关系-当依赖的模块更新后,我应该如何重新构建主项目
文章目录 一、前言二、Maven 常用命令一览三、典型场景说明四、正确的构建顺序正确做法是: 五、为什么不能只在 A 里执行 clean install?六、进阶推荐:使用多模块项目(Multi-module Project)七、总结 一、前言 在现代…...

遗传算法求解旅行商问题分析
目录 一、问题分析 二、实现步骤 1)初始化种群 2)计算适应度 3)选择操作 4)交叉操作 5)变异操作 三、求解结果 四、总结 本文通过一个经典的旅行商问题,详细阐述在实际问题中如何运用遗传算法来进…...
【hot100-动态规划-300.最长递增子序列】
力扣300.最长递增子序列思路解析 本题要求在一个整数数组 nums 中,找到最长严格递增子序列的长度。子序列是指从原数组中派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 动态规划思路 定义状态:…...
PostgreSQL malformed array literal异常
现象 在一个存储过程中编写如下代码(省略与本异常无关的代码): declare hbsn_arr varchar(240)[]; #bddm.hbsn 内容类似于{"chain0":["NULL"],"chain1":["FESDF09402342","NULL"],...} …...

打造网络安全堡垒,企业如何应对DDoS、CC、XSS和ARP攻击
网站已经成为企业展示形象、开展业务和实现线上营销的重要平台。然而,随着网络攻击手段的不断升级,DDoS、CC、XSS、ARP等攻击频频出现,严重威胁到企业的信息安全和业务稳定。本文将详细阐述网站被攻击后应采取的应急措施及预防策略࿰…...
Oracle统计信息收集时的锁持有阶段
Oracle统计信息收集时的锁持有阶段 1 准备阶段(共享模式锁) 锁类型:对象级共享锁(S锁) 持续时间:通常1-5秒 主要操作: 验证对象存在性和权限检查统计信息首选项设置确定采样方法和并行度 监…...

深度解析物理机服务器故障修复时间:影响因素与优化策略
一、物理机故障修复的核心影响因素 物理机作为企业 IT 基础设施的核心载体,其故障修复效率直接关系到业务连续性。故障修复时间(MTTR)受多重因素交叉影响: 1. 故障类型的复杂性 硬件级故障: 简单故障:内存…...