网络通讯核心知识
网络通讯核心知识
一、核心概念
1. Socket
是什么:进程间通信(IPC)的扩展机制
用途:建立网络通信通道(TCP/UDP)
流程:
- 服务端:socket → bind → listen → accept
- 客户端:socket → connect → write/read → close
注意事项:需处理字节序转换(htonl/ntohl)
2. TCP vs UDP
特性 | TCP | UDP |
---|---|---|
连接方式 | 面向连接(三次握手) | 无连接 |
可靠性 | 可靠传输(重传机制) | 不可靠传输 |
数据形式 | 流式套接字 | 数据报套接字 |
适用场景 | 文件传输、网页浏览 | 实时视频、DNS查询 |
二、服务器模型
1. 迭代服务器
缺陷:单线程阻塞,无法并发处理请求
2. 进程/线程模型
进程方案:
- 需用waitpid()避免僵尸进程
- 注意:子进程结束需父进程回收资源
僵尸进程处理详解:
-
产生原因:
- 子进程终止但未被父进程wait()
- 会占用系统进程表资源
-
处理方法:
- 同步回收:
waitpid(pid, NULL, 0); // 阻塞等待
- 异步回收(推荐):
signal(SIGCHLD, [](int) {while(waitpid(-1, NULL, WNOHANG) > 0); });
- 同步回收:
-
特殊情形:
- 父进程先终止时,僵尸进程由init进程接管并回收
- 批量回收时需循环调用waitpid()
线程方案:
- 需处理共享变量加锁问题
- 线程同步更复杂(临界区/锁机制)
3. 进程池优化
类型 | 特点 |
---|---|
静态进程池 | 预创建进程,限制并发上限 |
动态进程池 | 维护最小/最大空闲进程数 |
三、高性能I/O模型
1. 传统阻塞模型
特点:
- 单线程阻塞等待I/O就绪
- 资源利用率低
2. Select/Poll
特性 | Select | Poll |
---|---|---|
实现原理 | 位图轮询FD(描述符集) | 链表轮询FD(描述符集) |
最大连接数 | 1024(FD_SETSIZE限制) | 无硬性限制 |
效率缺陷 | O(n)线性扫描 | O(n)线性扫描 |
跨平台性 | 所有平台支持 | 所有平台支持 |
3. Epoll
核心机制:
- 事件注册:通过epoll_ctl维护红黑树
- 就绪列表:内核维护就绪FD双向链表
- 触发模式:
- LT(Level Trigger):类似Poll的触发方式
- ET(Edge Trigger):状态变化时单次通知
性能优势:
- O(1)事件通知复杂度
- 百万级连接支持(C1000K场景)
4. NIO(Non-blocking I/O)
核心组件:
- Channel:全双工通信管道(SocketChannel/FileChannel)
- Buffer:结构化数据容器(ByteBuffer/CharBuffer)
- Selector:多路复用器(基于系统epoll/kqueue实现)
工作流程:
start
: 创建Selector;
: 注册Channel到Selector;
repeat: select()查询就绪事件;: 处理SelectionKey事件;
repeat while (有事件?)
stop
5. AIO(Asynchronous I/O)
实现原理:
- 内核完成I/O操作后主动回调
- 无需用户线程轮询
典型场景:
- 大文件异步读写
- 高延迟网络操作
6. 完整对比表
模型 | 阻塞性 | 线程要求 | 触发方式 | 适用场景 |
---|---|---|---|---|
阻塞I/O | 完全阻塞 | 1:1 | - | 低并发简单场景 |
Select | 非阻塞 | 1:N | 轮询通知 | 跨平台中等并发 |
Poll | 非阻塞 | 1:N | 轮询通知 | 连接数<10K |
Epoll | 非阻塞 | 1:N | 事件驱动 | Linux高并发系统 |
NIO | 非阻塞 | 1:N | 就绪选择 | 高吞吐应用 |
AIO | 异步 | 0:1 | 完成回调 | 延迟敏感型操作 |
补充说明
-
内核支持:
- Windows:IOCP是真正的异步I/O
- Linux:5.1+内核的io_uring接近真异步
-
性能临界点:
- C10K:Select/Poll达到性能瓶颈
- C100K:必须使用Epoll/NIO
- C1000K:需要Epoll+零拷贝优化
-
编程复杂度:
- 阻塞I/O < Select < Poll < Epoll < NIO < AIO
四、实践要点
1. 守护进程
关键步骤:
- fork()
- setsid()
需重定向标准I/O至/dev/null
2. UDP服务器
特点:
- 无需listen()/accept()
- 直接使用recvfrom()/sendto()
3. 其他
- Reuse Address:避免TIME_WAIT状态占用端口
- 惊群效应:多进程Accept互相竞争导致,需内核锁优化
服务器类型: - IO密集型:LNMP(nginx)
- CPU密集型:LAMP(Apache)
- 协程:是用户态线程,用户态调度,避免内核切换开销,线程是内核调用。对比线程:切换速度更快,资源消耗更低
五、学习建议
1. 诊断工具
netstat -anp # 查看网络连接
2. 经典书籍
- 《Unix网络编程》
- 《Unix环境高级编程》