EPOLL_EVENTS
// 默认的触发模式是水平触发的,这里是边缘触发
// 水平触发是只要有就会触发,边缘触发是改变了才会触发,所以边缘触发要用while
#define EPOLLET 1u << 31(需要声明)
// 1. 监听到文件描述符可读
// 2. 文件描述符断开也会收到该事件
#define EPOLLIN 0x001(需要声明)
// 不了解...
#define EPOLLPRI 0x002
// 监听到文件描述符可写
#define EPOLLOUT 0x004(需要声明)
// 监听到文件描述符断开连接(会同时收到EPOLLIN | EPOLLRDHUP)
#define EPOLLRDHUP 0x2000(需要声明)
// 当对端socket_fd关闭的时候,会先触发EPOLLIN事件,因为收到了EPOLLIN事件,于是就会去读文件描述符,这时就会触发EPOLLERR和EPOLLHUP事件
// 表示监听到文件描述符发生错误
#define EPOLLERR 0x008(不需要声明)
// 表示监听到文件描述符断开连接
#define EPOLLHUP 0x010(不需要声明)
设置socket_fd非阻塞
void set_noblock(int socket_fd) {
if (socket_fd == -1) {
return;
}
int flags = fcntl(socket_fd, F_GETFL, 0);
if (flags < 0) {
return;
}
// fcntl: file control
// F_SETFL: file set flag
// O_NONBLOCK: 非阻塞flag
fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
}
errno
// 阻塞和非阻塞状态下都有可能产生EAGAIN错误码,但是一般用于非阻塞状态
// 非阻塞状态下,read操作时可能缓冲区为空,此时程序不会阻塞起来等待数据,而是直接返回错误码EAGAIN,提示稍后重试
// 非阻塞状态下,write操作可能缓冲区已满,此时程序不会阻塞起来等待缓冲区清出空间,而是直接返回错误码EAGAIN,提示稍后重试
EAGAIN
if(read_size == -1 && errno == EAGAIN){
// 继续重新尝试读写
}
// 中断,暂时不知道产生的具体原因
EINTR
int accept_socket_fd = accept(socket_fd, (sockaddr*)&sock_addr, &sock_addr_len);
if (accept_socket_fd == -1) {
if (errno == EINTR) {
// 处理中断
} else {
// 处理其它错误
}
}