I have written a simple TCP server socket and added the fd
to the epoll_cntl
. After the client is connected, the accept fd
is also added to the epoll_cntl
.
When the client is closed, I am receiving an unknown event through epoll_wait
. epoll event is receiving an event as 5 (kindly grep for the string "Issue seen here" in the code below.
Can someone help me out in understanding, why the epoll is receiving such an event?
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
is 5.
So the file descriptor is both readable and writable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.