我有一个侦听器套接字,我得到的每一个新连接都会像这样添加到epoll中:
int connfd = accept(listenfd, (struct sockaddr *)&clnt_addr, &clnt_addr_len);
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT | EPOLLHUP;
ev.data.fd = connfd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev)当接收到新数据时,epoll会向'EPOLLIN‘事件发出信号--正如预期的那样。
在这种情况下,我把所有资料看了如下:
long read = 0;
do {
read = recv(events[n].data.fd, buffer, sizeof (buffer), 0);
} while (read > 0);如果我野蛮地或正常地断开连接,epoll不会发出事件信号。
这段代码在每个线程中运行,这就是我使用的EPOLLET。
所以我的问题是:
发布于 2022-01-29 12:49:18
你的尝试有几个问题。
EPOLLONESHOT,除非你知道你在做什么,并且你真的需要它。它将任何其他事件的报告禁用到epoll实例,直到您再次使用EPOLL_CTL_MOD.启用它为止。
EPOLLHUP来确定连接是否已关闭。在从套接字输入流读取所有数据之前,可能会引发EPOLLHUP事件,即使客户端断开连接。我建议您只使用EPOLLIN。如果没有剩下来的输入(因为有力或优雅的断开),read()将返回0 (EOF),您可以关闭套接字.。
read()调用将阻塞读取线程并消耗整个流直到EOF (连接关闭)。使用epoll()的全部要点是不必使用while ( read(...) > 0 )循环.EPOLLET,因为“代码运行多线程”,而是因为您需要它。您可以不使用边缘触发模式编写多线程代码。使用EPOLLET需要彻底了解阻塞和非阻塞I/O之间的区别。您可以很容易地遇到陷阱(如手册中提到的),比如边缘触发的饥饿。https://stackoverflow.com/questions/70905227
复制相似问题