如何区分同一套接字上的读取和写入事件?

6
我使用epoll来获取有关传入数据的通知。这并不难,因为epoll_wait()返回的所有事件都表明我可以从epoll_event.data.fd(套接字描述符)读取数据。但现在我想要同时获得两种类型的通知:接收和发送(套接字可用于发送)。但是我无法这样做,因为:
  1. 由epoll_wait()返回的epoll_event.events与我在epoll_ctl()中传递的相同。所以在我的情况下它同时包含EPOLLIN和EPOLLOUT。
  2. 如果我尝试将一个套接字作为EPOLLIN事件和EPOLLOUT事件两次添加到epoll中,我将得到EEXIST错误。
如何解决这个问题而不是每次收到通知时手动调用select()?
2个回答

6

man epoll_wait 明确说明了“事件成员将包含返回的事件位字段”。因此,如果在 epoll_event.events 中获取 EPOLLIN | EPOLLOUT,则表示您的套接字必须准备好读和写。

如果您只想在套接字“状态更改”时收到通知,请使用 EPOLLET 进行边缘触发操作。


5

使用epoll_ctl添加描述符时,将events掩码设置为EPOLLIN | EPOLLOUT

当您通过epoll_wait收到通知时,需要循环返回的通知并检查EPOLLINEPOLLOUT

伪代码

int index, count;
count = epoll_wait(epfd, epoll_event, MAX_EVENTS, -1);
for (index = 0; index < count; ++index) {
  if (epoll_event[index].events & EPOLLIN) {
    // Ready for read
  }

  if (epoll_event[index].events & EPOLLOUT) {
    // Ready for write
  }
}

有些人只在发送缓冲区中存在数据时设置EPOLLOUT位。我没有包含任何错误检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接