在侦听套接字上,我设置了EPOLLIN
位,但是在客户端连接上,我将EPOLLIN | EPOLLOUT
位设置为struct epoll_event
:
struct epoll_event ev;
ev.data.fd = fd;
ev.events = EPOLLIN | EPOLLOUT;
if (epoll_ctl(evs->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
...
这就是我测试位的方式:
if ((events & EPOLLIN) == EPOLLIN)
...
if ((events & EPOLLOUT) == EPOLLOUT)
...
我也尝试过:
if (events & EPOLLIN)
...
if (events & EPOLLOUT)
...
两种方式总是正确的!
然而,每当我在我的 epoll fd 上调用 epoll_wait 时,返回的活动文件描述符总是设置两个位,即使 send() 没有返回 EAGAIN,但是当我尝试 recv() 时它返回 EAGAIN。
我不知道当 recv() 返回 EAGAIN 时我应该做什么,我应该删除EPOLLOUT
标志还是什么?
@Nikolai N Fetissov 要求的更多代码:
static int get_active_fd(events *evs, int index, sstate_t *flags)
{
uint32_t events = evs->events[index].events;
int fd = evs->events[index].data.fd;;
if ((events & EPOLLERR) == EPOLLERR || (events & EPOLLHUP) == EPOLLHUP) {
close(fd);
return -1;
}
if (events & EPOLLIN)
*flags |= DATA_IN;
return fd;
}
void sockset_add(events *evs, int fd)
{
struct epoll_event ev;
...
ev.data.fd = fd;
ev.events = EPOLLIN;
if (epoll_ctl(evs->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
eprintf("sockset_add(): epoll_ctl(%d) returned an error %d(%s)\n",
fd, errno, strerror(errno));
}
然后稍后我调用 epoll_wait():
if (flags & DATA_IN) {
/* try to read which is impossible because this is never set. */