[英]epoll_wait receiving an unknown event
I have written a simple TCP server socket and added the fd
to the epoll_cntl
. 我编写了一个简单的TCP服务器套接字,并将
fd
添加到epoll_cntl
。 After the client is connected, the accept fd
is also added to the epoll_cntl
. 客户端连接后,accept
fd
也添加到epoll_cntl
。
When the client is closed, I am receiving an unknown event through epoll_wait
. 当客户端关闭时,我通过
epoll_wait
接收到未知事件。 epoll event is receiving an event as 5 (kindly grep for the string "Issue seen here" in the code below. epoll事件接收的事件为5(在下面的代码中,grep为字符串“ Issue seen here”) 。
Can someone help me out in understanding, why the epoll is receiving such an event? 有人可以帮助我理解为什么epoll会收到这样的事件吗?
Here's my code: 这是我的代码:
int ControllerTask()
{
int retval = 0;
int res = 0;
static struct epoll_event ev;
g_epfd = epoll_create1(0);
/* Create TCP Server Socket */
retval = createTcpServerSock();
if(retval < 0)
{
return 0;
}
ev.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET;
ev.data.fd = g_server_fd[0];
res = epoll_ctl(g_epfd, EPOLL_CTL_ADD, g_server_fd[0], &ev);
acceptIncomingData();
}
int createTcpServerSock()
{
int retval = -1;
struct sockaddr_in addr;
int sockOpt = 0;
int reuse = 1;
do
{
if((g_server_fd[0] = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("sock_failed");
return 0;
}
sockOpt = fcntl(g_server_fd[0], F_GETFL);
if(sockOpt < 0)
break;
sockOpt |= O_NONBLOCK;
if (fcntl(g_server_fd[0], F_SETFL, sockOpt) < 0)
break;
if ((retval = setsockopt(g_server_fd[0], SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse))) < 0)
break;
if ((retval = setsockopt(g_server_fd[0], SOL_SOCKET, SO_KEEPALIVE, (const char*)&reuse, sizeof(reuse))) < 0)
break;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(7000);
if(bind(g_server_fd[0], (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind failed");
break;
}
listen(g_server_fd[0], SOMAXCONN);
retval = 0;
}while(0);
return retval;
}
void acceptIncomingData()
{
struct epoll_event *events;
int nfds, i, err;
int n_bytes = 0;
events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * MAX_EPOLL_EVENTS);
memset(events, 0, sizeof(struct epoll_event) * MAX_EPOLL_EVENTS);
g_buff = (void *)malloc(MAX_MSG_SIZE * sizeof(char *));
memset(g_buff, 0, MAX_MSG_SIZE * sizeof(char *));
while(1) {
nfds = epoll_wait(g_epfd, events, MAX_EPOLL_EVENTS, EPOLL_WAIT_TIMEOUT);
if(!nfds)
{
continue;
}
else if(nfds < 0)
{
perror("epoll_wait");
return;
}
printf("Some data in EPOLL\n");
for(i = 0; i < nfds; i++) {
if ((events[i].events & EPOLLERR) ||
(events[i].events & EPOLLHUP))
{
printf("TCP close connection\n");
closeTcpConnection(events[i].data.fd);
return;
}
else
{
else if(EPOLLIN == events[i].events)
{
if(events[i].data.fd == g_server_fd[0])
{
acceptIncomingConns(events[i].data.fd);
printf("Accept incoming data\n");
continue;
}
n_bytes = read(events[i].data.fd, g_buff, sizeof(g_buff));
if(n_bytes == -1)
{
if(errno != EAGAIN)
{
perror("read");
}
}
else if(n_bytes == 0)
{
printf("n_bytes = 0\n");
continue;
}
else
{
printf("n_bytes = %d\n", n_bytes);
handleSocketEvents(g_buff);
}
}
else
{
/* Issue seen here: Receiving event as 5 which is not defined */
printf("In else. Event : %d\n", events[i].events);
}
}
}
}
}
}
int acceptIncomingConns(int fd)
{
/* accFd = TCP accept FD */
int accFd = 0;
int s, i;
int sockOpt = 0;
struct sockaddr in_addr;
int in_len;
struct epoll_event event;
while(1)
{
accFd = accept(fd, &in_addr, &in_len);
if(accFd == -1)
{
if((errno == EAGAIN) || (errno == EWOULDBLOCK))
{
break;
}
else
{
perror("accept");
break;
}
}
g_server_fd[1] = accFd;
sockOpt = fcntl(accFd, F_GETFL);
sockOpt |= O_NONBLOCK;
fcntl(accFd, F_SETFL, sockOpt);
event.data.fd = accFd;
event.events = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLERR | EPOLLHUP;
s = epoll_ctl(g_epfd, EPOLL_CTL_ADD, accFd, &event);
}
}
void closeTcpConnection(int delFd)
{
int i = 0;
close(delFd);
g_server_fd[1] = 0;
return;
}
The events field is a bitmask. 事件字段是一个位掩码。
EPOLLIN
is 1. EPOLLOUT
is 4. Therefore EPOLLIN | EPOLLOUT
EPOLLIN
为EPOLLOUT
为4 EPOLLIN | EPOLLOUT
EPOLLIN | EPOLLOUT
is 5. EPOLLIN | EPOLLOUT
为5。
So the file descriptor is both readable and writable. 因此,文件描述符是可读可写的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.