【发布时间】:2016-08-18 06:22:21
【问题描述】:
我用epoll写了一个tcp服务器,在Ubuntu上可以正常工作,但是在CentOS7上偶尔会发生奇怪的事情。
客户端a尝试连接服务器b,连接已建立, 客户端的端口是59298,服务端的端口是8802,服务端的socketfd是16。
[同步]
[syn,ack]
[确认]
同时服务器读取事件,返回值为零,sockfd 相同,即 16,与之前建立的连接相同,告诉 a 和 b 之间的连接已关闭。服务器使用不同的端口向客户端发送一个 [rst,ack] 包,即 59191。为什么会发生这种情况?是centos内核的bug吗?
我的代码与下面的非常相似。
#define MAX_EVENTS 10
struct epoll_event ev, events[MAX_EVENTS];
int listen_sock, conn_sock, nfds, epollfd;
/* Set up listening socket, 'listen_sock' (socket(),
bind(), listen()) */
epollfd = epoll_create(10);
if (epollfd == -1) {
perror("epoll_create");
exit(EXIT_FAILURE);
}
ev.events = EPOLLIN;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
for (;;) {
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (nfds == -1) {
perror("epoll_pwait");
exit(EXIT_FAILURE);
}
for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == listen_sock) {
conn_sock = accept(listen_sock,
(struct sockaddr *) &local, &addrlen);
if (conn_sock == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
&ev) == -1) {
perror("epoll_ctl: conn_sock");
exit(EXIT_FAILURE);
}
} else {
do_use_fd(events[n].data.fd);
}
}
}
【问题讨论】:
标签: linux sockets tcpdump epoll