linux高性能服务器编程---第九章 I/O复用 (1)
I/O复用使得程序能同时监听多个文件描述符.
- 客户端程序需要同时处理多个socket 非阻塞connect技术
- 客户端程序同时处理用户输入和网络连接 聊天室程序
- TCP服务器要同时处理监听socket和连接socket
- 同时处理TCP和UDP请求 - 回射服务器
- 同时监听多个端口, 或者处理多种服务 - xinetd服务器
常用手段select
, poll
, epoll
select
#include <sys/select.h> // nfds - 被监听的文件描述符总数 // 后面三个分别指向 可读, 可写, 异常等事件对应的文件描述符集合 // timeval select超时时间 如果传递0 则为非阻塞, 设置为NULL则为阻塞 // 成功返回就绪(可读, 可写, 异常)文件描述符的总数, 没有则返回0 失败返回-1 int select (int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout); //操作fd_set的宏 FD_ZERO(fd_set* fdset); FD_SET(int fd, fd_set* fdset); FD_CLR(int fd, fd_set* fdset); FD_ISSET(int fd, fd_set* fdset); // 设置 timeval 超时时间 struct timeval { long tv_sec; // 秒 long tv_usec; // 微秒 }
select
文件描述符就绪条件
- socket内核接收缓存区中的字节数大于或等于 其低水位标记
- socket通信的对方关闭连接, 对socket的读操作返回0
- 监听socket上有新的连接请求
- socket上有未处理的错误, 可以使用getsockopt来读取和清除错误
- socket内核的发送缓冲区的可用字节数大于或等于 其低水位标记
- socket的写操作被关闭, 对被关闭的socket执行写操作将会触发一个SIGPIPE信号
- socket使用非阻塞connect 连接成功或失败后