06 网络2
06 网络2
参考资料:9.2 I/O 多路复用:select/poll/epoll | 小林coding (xiaolincoding.com)
select
select
允许程序同时监视多个文件描述符(通常是套接字描述符),以确定是否有任何文件描述符准备好读取、写入或有错误。它是一种在单个线程中处理多个 I/O 操作的机制。
函数原型
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); |
参数
-
nfds
: 需要监视的最大文件描述符加1。例如,如果你监视的最大文件描述符是 5,则nfds
应该是 6。 -
readfds
: 指向一个集合,包含需要监视读取状态的文件描述符。 -
writefds
: 指向一个集合,包含需要监视写入状态的文件描述符。 -
exceptfds
: 指向一个集合,包含需要监视异常条件的文件描述符。 -
timeout
: 指向一个timeval
结构,指定select
调用的超时时间。如果为 NULL,则select
会一直阻塞直到有文件描述符准备好。
返回值
-
成功时,返回准备好的文件描述符的数量。
-
错误时,返回-1。
fd_set
结构体
fd_set
是一个用于 select
函数的特定数据结构,它能够存储一组非负的文件描述符(通常是套接字)。这个结构体在 <sys/select.h>
头文件中定义,但它的具体实现是依赖于平台的。
-
FD_ZERO(fd_set *set)
: 这个宏将fd_set
初始化为空集合,即没有任何文件描述符。 -
FD_SET(int fd, fd_set *set)
: 这个宏将文件描述符fd
添加到fd_set
集合中。 -
FD_CLR(int fd, fd_set *set)
: 这个宏从fd_set
集合中移除文件描述符fd
。 -
FD_ISSET(int fd, fd_set *set)
: 这个宏检查文件描述符fd
是否在fd_set
集合中。
struct timeval
结构体
timeval
结构体用于指定时间间隔,它在 <sys/time.h>
头文件中定义。select
函数使用它来设置操作的超时时间。
-
struct timeval { long tv_sec; // 秒 long tv_usec; // 微秒 };
服务器示例
|
poll
poll
是一种比 select
更灵活的 I/O 多路复用技术,它允许程序同时监视多个文件描述符,以确定是否有任何文件描述符准备好进行读取、写入或出现错误。与 select
不同,poll
没有最大文件描述符数量的限制,并且可以监视更多的事件类型。
函数原型
int poll(struct pollfd *fds, nfds_t nfds, int timeout); |
参数
-
fds
: 指向一个pollfd
结构体数组,每个结构体代表一个要监视的文件描述符。 -
nfds
: 数组中的结构体数量。 -
timeout
: 指定poll
调用的超时时间(毫秒)。如果为 -1,则poll
会一直阻塞直到有文件描述符准备好。
返回值
-
成功时,返回准备好的文件描述符的数量。
-
错误时,返回 -1。
struct pollfd
结构体
pollfd
结构体用于 poll
函数,它定义了要监视的文件描述符和相关的事件。
struct pollfd { |
-
events
字段可以是以下宏的组合:POLLIN
: 文件描述符可读。POLLOUT
: 文件描述符可写。POLLERR
: 出现错误。POLLHUP
: 对端关闭连接。
-
revents
字段在poll
返回后,会设置为以下宏的组合之一:POLLIN
: 有数据可读。POLLOUT
: 可以写入数据。POLLERR
: 检测到错误。POLLHUP
: 对端关闭连接。
服务器示例
以下是一个使用 poll
的简单 echo 服务器示例:
|
epoll
了解您的需求,我会给出一个完整的 epoll
示例,包括每个函数的原型、参数说明、返回值,以及一个完整的服务器示例代码。
epoll_create
函数原型
int epoll_create(int size); |
参数说明
-
size
: 指定了epoll实例所能同时监控的文件描述符的数量。这个参数并不是限制最大并发数量,而是一个提示给内核的初始大小。
返回值
-
成功时,返回一个新的 epoll 实例的文件描述符。
-
错误时,返回 -1,并设置
errno
以指示错误。
epoll_create1
函数原型
int epoll_create1(int flags); |
参数说明
-
flags
: 可以是以下标志的组合:EPOLL_CLOEXEC
: 设置close-on-exec
属性。0
:无特殊行为
返回值
-
成功时,返回一个新的 epoll 实例的文件描述符。
-
错误时,返回 -1,并设置
errno
以指示错误。
epoll_ctl
函数原型
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); |
参数说明
-
epfd
: epoll 实例的文件描述符。 -
op
: 操作类型,可以是EPOLL_CTL_ADD
(添加)、EPOLL_CTL_MOD
(修改)或EPOLL_CTL_DEL
(删除)。 -
fd
: 要操作的文件描述符。 -
event
: 指向epoll_event
结构体的指针,包含了要设置的事件和用户数据。
返回值
-
成功时,返回 0。
-
错误时,返回 -1,并设置
errno
以指示错误。
epoll_wait
函数原型
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); |
参数说明
-
epfd
: epoll 实例的文件描述符。 -
events
: 指向epoll_event
结构体数组的指针,用于接收发生的事件。 -
maxevents
:events
数组的最大容量。 -
timeout
: 等待时间,单位为毫秒。-1 表示无限期等待。
返回值
-
成功时,返回数组中已填充的事件数量。
-
错误时,返回 -1,并设置
errno
以指示错误。
epoll_event 结构体
struct epoll_event { |
epoll 服务器示例
|
练习
-
file server 用epoll改写一下