简体   繁体   English

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

[英]How can I distinguish read and write events on the same socket?

I'm using epoll to get notifications about incoming data. 我正在使用epoll来获取有关传入数据的通知。 It's not hard because all events returned by epoll_wait() indicates, that I can read data from epoll_event.data.fd (socket descriptor). 这并不难,因为epoll_wait()返回的所有事件都表明,我可以从epoll_event.data.fd (套接字描述符)中读取数据。

But now I want get both types of notification: receiving and sending (socket is available for send). 但现在我想得到两种类型的通知:接收和发送(套接字可用于发送)。 But I can't to do it because: 但我不能这样做是因为:

  1. epoll_event.events which is returned by epoll_wait() is the same as I pass in epoll_ctl() . epoll_event.events epoll_wait()返回的epoll_wait()与我在epoll_ctl()传递的相同。 So it contains both EPOLLIN and EPOLLOUT in my case. 所以它在我的例子中包含EPOLLINEPOLLOUT
  2. Also if i trying to twice add one socket in epoll (as EPOLLIN and as EPOLLOUT event) I'll get a EEXIST . 此外,如果我试图两次在epoll添加一个套接字(作为EPOLLIN和EPOLLOUT事件),我将得到一个EEXIST

How can I solve this problem without manually calling select() every time I get notification? 每次收到通知时,如果不手动调用select()如何解决此问题?

man epoll_wait clearly states that "the events member will contain the returned event bit field.". man epoll_wait明确指出“事件成员将包含返回的事件位字段。” Therefore, if you are getting EPOLLIN | EPOLLOUT 因此,如果你得到EPOLLIN | EPOLLOUT EPOLLIN | EPOLLOUT in epoll_event.events , then your socket must be ready for both reading and writing. EPOLLIN | EPOLLOUT中的epoll_event.events ,那么你的套接字必须准备好进行读写。

If you only want to be notified when the socket changes state , use EPOLLET for edge-triggered operation. 如果您只想在套接字更改状态时收到通知,请使用EPOLLET进行边沿触发操作。

When you add a descriptor using epoll_ctl , set the events mask to be EPOLLIN | EPOLLOUT 使用epoll_ctl添加描述符时,将events mask设置为EPOLLIN | EPOLLOUT EPOLLIN | EPOLLOUT . EPOLLIN | EPOLLOUT

When you get notifications via epoll_wait then you'd loop through the returned notifications checking for EPOLLIN and EPOLLOUT . 当您通过epoll_wait收到通知时,您将循环检索EPOLLINEPOLLOUT的返回通知。

Pseudo code : 伪代码

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
  }
}

Some people only set the EPOLLOUT bit when they have data present in their send buffer. 有些人只有在发送缓冲区中存在数据时才设置EPOLLOUT位。 I did not include any error checking. 我没有包含任何错误检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM