第4周:Socket 编程深入
目标:掌握非阻塞 I/O、I/O 多路复用,使用 epoll 实现高并发服务器。
1. Socket 基础 API
1.1 TCP Socket 完整流程
1 |
|
1.2 UDP Socket
1 |
|
2. I/O 模型对比
2.1 五种 I/O 模型
1 | 阻塞 I/O (Blocking I/O): |
2.2 阻塞 vs 非阻塞对比
1 |
|
3. select
3.1 使用方式
1 |
|
3.2 select 的局限
| 问题 | 说明 |
|---|---|
| fd_set 上限 | FD_SETSIZE 通常 1024 |
| O(n) 扫描 | 每次 select 要遍历整个 fd_set |
| fd_set 复制 | 每次调用从用户态拷贝到内核态 |
| fd 范围 | 只能管理 0 ~ max_fd |
4. poll
4.1 poll 使用方式
1 |
|
4.2 poll vs select
| 特性 | select | poll |
|---|---|---|
| fd 上限 | 1024 (FD_SETSIZE) | 无硬性限制 |
| 数据结构 | fd_set (bitmap) | pollfd 数组 |
| 每次调用 | 复制 fd_set | 复制 pollfd 数组 |
| 事件类型 | 只读/写/异常 | 更丰富 (POLLIN/OUT/PRI/ERR/HUP) |
| 性能 | O(n) 扫描 | O(n) 扫描 |
5. epoll
5.1 epoll 核心 API
1 |
|
5.2 Level Triggered (LT) vs Edge Triggered (ET)
1 | Level Triggered (LT,默认): |
1 | // ET 模式注册 |
ET 优点:减少 epoll_wait 返回次数,高并发下性能更好。
ET 缺点:必须用非阻塞 I/O + 循环读写,实现复杂。
5.3 完整 epoll 实现
1 | // epoll_echo_server.c |
1 | gcc -o epoll_echo epoll_echo_server.c |
5.4 epoll_event 详解
1 | struct epoll_event { |
5.5 EPOLLONESHOT 用法
1 | // 适用于每个 fd 只有一个线程处理的场景 |
6. 连接管理:多进程 + SO_REUSEPORT
1 | // 多进程 epoll 服务器,利用 SO_REUSEPORT 负载均衡 |
SO_REUSEPORT 优势:
- 内核级别的负载均衡(哈希或轮询分发新连接到不同 socket)
- 避免惊群(多个进程同时被 accept 唤醒)
- 多核利用,每个进程可以绑到不同 CPU
7. epoll 性能对比
1 | 连接数 | select | poll | epoll(LT) | epoll(ET) |
8. 常见问题排查
1 | // === EPOLLHUP 的处理 === |
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/07/30/第4周:Socket 编程深入/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!