Linux网络编程,高性能 IO 多路复用服务器:向 epoll 监控器注册要监听的 socket 和事件

cpp 复制代码
// 5. 将监听套接字添加到epoll监控
    struct epoll_event event{};
    event.events = EPOLLIN; // 监控可读事件
    event.data.fd = listen_sockfd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sockfd, &event) < 0) {
        perror("epoll_ctl add listen failed");
        return 1;
    }

把监听套接字加入 epoll 监控

这是 epoll 高并发服务器最核心的操作之一向 epoll 监控器注册要监听的 socket 和事件

整段代码的核心作用(大白话)

c 复制代码
// 告诉 epoll 监控中心:
// 帮我盯着【监听套接字】,一旦有客户端来连接(可读事件),立刻通知我!

这一步 = 给服务器装上"雷达",开始扫描客户端连接请求。


逐行深度拆解

1. 创建 epoll 事件结构体

c 复制代码
struct epoll_event event{};

这是什么?

  • epoll_eventepoll 事件描述体
  • 作用:告诉 epoll 要监听哪个 socket、监听什么事件、事件触发后带什么数据回来

结构体内部长这样(必须看懂):

c 复制代码
struct epoll_event {
    uint32_t events;  // 要监听的事件类型(如:可读、可写、异常)
    epoll_data_t data; // 事件触发时,带回的数据(通常存 socket 文件描述符)
};

2. 设置要监听的事件类型

c 复制代码
event.events = EPOLLIN; // 监控可读事件

EPOLLIN 是什么?

全称:Event POLL IN ------ 监听「可读事件」

  • 含义:只要对应的 socket 有数据可读,就触发通知
  • 监听套接字 来说:
    EPOLLIN 事件触发 = 有客户端来连接了!

为什么监听套接字只需要 EPOLLIN?

  • 监听套接字不收发数据 ,只负责接收新连接
  • 客户端发起连接 → 内核把连接放入队列 → 监听套接字变为「可读」
  • epoll 检测到 EPOLLIN → 通知程序去调用 accept() 接收连接

其他常见事件(了解即可):

  • EPOLLOUT:可写事件(发送数据时用)
  • EPOLLET:边缘触发(高性能模式)
  • EPOLLERR:异常事件

3. 设置事件触发后带回的数据

c 复制代码
event.data.fd = listen_sockfd;

作用:

把监听套接字的文件描述符存进事件结构体

  • 当 epoll 检测到事件触发时,会把这个 fd 原样返回
  • 程序拿到 fd 就知道:哦!是监听套接字有动静了,该去 accept 了!

为什么要存 fd?

epoll 会监控成百上千个 socket

必须带上标识,才能知道到底是哪个 socket 触发了事件


4. 核心函数:epoll_ctl(操控 epoll 监控列表)

c 复制代码
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sockfd, &event)

① 函数作用

对 epoll 监控列表进行增、删、改操作

  • 增:添加要监控的 socket
  • 删:取消监控
  • 改:修改监控的事件类型

② 四个参数逐行解释(重中之重)

参数 含义 解释
epoll_fd epoll 实例的文件描述符 你之前 epoll_create1 创建的监控器
EPOLL_CTL_ADD 操作类型:添加 把 socket 加入 epoll 监控列表
listen_sockfd 要监控的目标 socket 监听套接字(负责接收客户端连接)
&event 事件配置信息 告诉 epoll:监听 EPOLLIN 事件,触发后返回 listen_sockfd

③ 三种操作类型(必记)

  • EPOLL_CTL_ADD添加 新的 socket 到 epoll
  • EPOLL_CTL_DEL删除 不再监控的 socket
  • EPOLL_CTL_MOD修改 已添加 socket 的监听事件

5. 返回值判断

c 复制代码
if (...) < 0) {
    perror("epoll_ctl add listen failed");
    return 1;
}
  • 成功:返回 0
  • 失败:返回 -1
  • 常见失败原因:
    • epoll_fd 非法
    • listen_sockfd 未绑定/未监听
    • 重复添加同一个 socket

完整原理(通俗到离谱)

把 epoll 当作 小区保安室

  1. struct epoll_event event = 一张监控登记表
  2. event.events = EPOLLIN = 登记要监控:有人来访
  3. event.data.fd = listen_sockfd = 监控目标:小区大门
  4. epoll_ctl(..., EPOLL_CTL_ADD, ...) = 把登记表交给保安
  5. 保安(epoll)开始盯着大门,有人来就立刻通知你

这行代码执行完后发生了什么?

  1. 内核把 listen_sockfd 加入 epoll 监控红黑树
  2. epoll 开始自动监控该套接字的 EPOLLIN 事件
  3. 一旦有客户端连接 → 内核立刻通知 epoll
  4. 程序调用 epoll_wait 就能拿到事件,去处理连接

极简总结(超好记)

  1. struct epoll_event:epoll 事件登记表
  2. EPOLLIN:监听「有客户端连接」事件
  3. event.data.fd:告诉 epoll,触发后带回监听套接字
  4. epoll_ctl(ADD) :把监听套接字注册到 epoll 监控
  5. 核心意义 :让 epoll 帮你盯着端口,有连接就通知,不用死等

一句话总结

这行代码 = 给 epoll 装上"连接雷达",让服务器能高效感知所有客户端的连接请求!

下一步就是最关键的 epoll_wait() ------ 等待客户端连接 / 数据到来

相关推荐
多巴胺梦想家5 分钟前
数据库恢复技术:当灾难来临
网络·数据库·oracle
一口一口吃成大V1 小时前
lattice mipi ip开启DESKEW_EN属性(“ENABLED“),输出异常
网络·网络协议·tcp/ip
技术不好的崎鸣同学2 小时前
[GXYCTF2019]Ping Ping Ping 思路及解法
网络·安全·web安全
hongmai6668882 小时前
GD5F1GM7REYIG存储芯片:1Gb SPI NAND Flash助力国产设备高效运行
网络·单片机·嵌入式硬件·物联网·智能家居
不会调制解调的猫2 小时前
笔记 | 什么是 rp_filter(反向路径过滤)?
服务器·网络·笔记
treesforest3 小时前
高精度IP定位怎么选?从企业需求出发的选型指南
网络·数据库·tcp/ip·web安全·ip·高精度ip查询
WZF-Sang3 小时前
网络层协议和数据链路层协议
网络
XR1234567883 小时前
食品饮料与制药行业GMP合规网络建设:无尘车间的网络不能成为污染源
开发语言·网络·php
丑过三八线4 小时前
【VMware Workstation NAT 网络配置指南】
网络
阿拉斯攀登4 小时前
并发与同步:自旋锁、信号量、互斥锁
linux·网络·嵌入式硬件·linux驱动·字符设备驱动