Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)

时间:2023-03-09 01:01:19
Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)

Linux下测试代码:

http://www.linuxhowtos.org/C_C++/socket.htm

TCP模型

 //TCPClient.c
#include<string.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#define MYPORT 4000
#define BACKLOG 10
#define MAX_LEN 100 int main(void)
{
int sockfd;
int tmp_int;
char *msg_send = NULL;
char *msg_recv = NULL;
int sin_size;
int len,bytes_sent,bytes_recv;
struct sockaddr_in my_addr;
struct sockaddr_in dest_addr; sockfd=socket(AF_INET,SOCK_STREAM,);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
bzero(&(my_addr.sin_zero),);
tmp_int = connect(sockfd,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr));
if( tmp_int < )
{
printf("ERROR:connect erro %s!\n", strerror(errno));
close(sockfd);
return -;
}
msg_send="This is TCPClient!\n";
len=strlen(msg_send);
bytes_sent=send(sockfd,msg_send,len,);
while( len != bytes_sent )
{
tmp_int = bytes_sent;
len -= bytes_sent;
printf("send %d,%d packet!\n", bytes_sent,len);
bytes_sent = send( sockfd, msg_send+tmp_int, len, );
}
msg_recv = (char *)malloc( MAX_LEN );
if( NULL == msg_recv )
{
printf("ERROR:malloc mem error!\n");
close(sockfd);
return -;
}
memset(msg_recv, , MAX_LEN );
bytes_recv=recv(sockfd,msg_recv,MAX_LEN,);
if( bytes_recv > )
{
printf("recv: %s\n!", msg_recv );
}
else
{
printf("ERROR:net error\n");
}
close(sockfd);
return ;
}
 //TCPServer.c
#include<string.h>
#include<errno.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#define MYPORT 4000
#define BACKLOG 10
#define MAX_LEN 100 int main(void)
{
int sockfd;
char* msg_send;
char* msg_recv;
int sin_size;
int new_fd;
int tmp_int;
int len,bytes_sent,bytes_recv;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr; sockfd=socket(AF_INET,SOCK_STREAM,);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
bzero(&(my_addr.sin_zero),);
bind(sockfd,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr));
listen(sockfd,BACKLOG);
sin_size=sizeof(struct sockaddr_in);
new_fd=accept(sockfd,(struct sockaddr *)&their_addr, &sin_size);
msg_send="This is TCPServer!\n";
len=strlen(msg_send);
bytes_sent=send(new_fd,msg_send,len,);
while( len != bytes_sent )
{
tmp_int = bytes_sent;
len -= bytes_sent;
printf("send %d packet\n", bytes_sent);
bytes_sent = send( new_fd, msg_send+tmp_int, len, );
}
msg_recv = (char *)malloc( MAX_LEN );
if( NULL == msg_recv )
{
printf("ERROR:malloc mem error!\n");
close(new_fd);
return -;
}
memset(msg_recv, , MAX_LEN );
bytes_recv=recv(new_fd,msg_recv,MAX_LEN,);
if( bytes_recv > )
{
printf("recv: %s\n", msg_recv );
}
else
{
printf("ERROR:net error!\n");
}
close(new_fd);
close(sockfd);
return ;
}

UDP模型

 //UDPServer.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h> #define RET_OK 0
#define RET_ERR -1
#define LISTEN_QUEUE_NUM 5
#define BUFFER_SIZE 256
#define ECHO_PORT 2029 int main(int argc, char **argv)
{
int sockfd, len, opt = ;
struct sockaddr_in cliaddr;
uint8_t buffer[BUFFER_SIZE];
int ret = RET_OK; if((sockfd = socket(AF_INET, SOCK_DGRAM, )) < )
{
perror("ERROR: opening socket!");
return RET_ERR;
}
if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < )
{
perror("ERROR: set sockopt!");
close(sockfd);
return ;
}
memset(&cliaddr, , sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = INADDR_ANY;
cliaddr.sin_port = htons(ECHO_PORT);
if ((ret = bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))) < )
{
perror("ERROR: on binding");
goto failed;
} do
{
len = sizeof(cliaddr);
if((ret = recvfrom(sockfd, buffer, sizeof(buffer), , (struct sockaddr *)&cliaddr, &len)) > )
{
printf("Recv from %s\r\n", inet_ntoa(cliaddr.sin_addr));
ret = sendto(sockfd, buffer, ret, , (struct sockaddr *)&cliaddr, len);
}
}while(ret >= ); close(sockfd);
return ;
}
 //UDPClient.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h> #define RET_OK 0
#define RET_ERR -1
#define LISTEN_QUEUE_NUM 5
#define BUFFER_SIZE 256
#define ECHO_PORT 2029 int main(int argc, char *argv[])
{
int sockfd, ret = RET_OK;
struct sockaddr_in servaddr;
struct hostent *server;
char buffer[BUFFER_SIZE]; if (argc < ) {
fprintf(stderr,"ERROR: usage %s hostname\n", argv[]);
return RET_ERR;
}
if((server = gethostbyname(argv[])) == NULL)
{
herror("ERROR: get host by name. ");
return RET_ERR;
} if((sockfd = socket(AF_INET, SOCK_DGRAM, )) < )
{
perror("ERROR: opening socket");
return RET_ERR;
}
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = *(uint32_t *)server->h_addr;
servaddr.sin_port = htons((uint16_t)ECHO_PORT); while()
{
printf("Enter the message : ");
if(fgets(buffer, sizeof(buffer) - , stdin) == NULL)
{
break;
}
if((ret = sendto(sockfd, buffer ,strlen(buffer), , (struct sockaddr *)&servaddr, sizeof(servaddr))) < )
{
perror("ERROR: writing to socket");
break;
}
if((ret = recvfrom(sockfd, buffer, sizeof(buffer) - , , NULL, NULL)) < )
{
perror("ERROR: reading from socket");
break;
}
buffer[ret] = ;
printf("Server echo message: %s\n",buffer);
}
close(sockfd);
return ret < ? RET_ERR : RET_OK;
}
 #Makefile

 PROGRAM_CLIENT = client
PROGRAM_SERVER = server CC = gcc LDPATH = /usr/local/lib INCLUDEDIR = . SOURCE_PATH = . OPTS = -g -Wall -I. -I$(INCLUDEDIR) CFLAGS = $(OPTS) -fPIC LIBS = -L./ -L$(LDPATH) all: $(PROGRAM_SERVER) $(PROGRAM_CLIENT) clean:
rm -f *.o *.core *.bak $(PROGRAM_CLIENT) $(PROGRAM_SERVER) *.a core.* *.exe $(PROGRAM_CLIENT): $(LIBRARY) $(SOURCE_PATH)/client.c
$(CC) $(CFLAGS) $(SOURCE_PATH)/client.c $(LIBS) -o $(PROGRAM_CLIENT) $(OBJS) -Wl,-rpath,./ $(PROGRAM_SERVER): $(LIBRARY) $(SOURCE_PATH)/server.c
$(CC) $(CFLAGS) $(SOURCE_PATH)/server.c $(LIBS) -o $(PROGRAM_SERVER) $(OBJS) -Wl,-rpath,./

select模型

 //server.c
#include <sys/types.h>
#include <ctype.h>
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <stdlib.h> #define LISTEN_QUEUE_NUM 5
#define BUFFER_SIZE 256
#define ECHO_PORT 2029 int main(int argc, char **argv)
{
struct sockaddr_in servaddr, remote;
int request_sock, new_sock;
int nfound, fd, maxfd, bytesread;
uint32_t addrlen;
fd_set rset, set;
struct timeval timeout;
char buf[BUFFER_SIZE]; if ((request_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < ) {
perror("socket");
return -;
}
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons((uint16_t)ECHO_PORT); if (bind(request_sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < )
{
perror("bind");
return -;
}
if (listen(request_sock, LISTEN_QUEUE_NUM) < )
{
perror("listen");
return -;
} FD_ZERO(&set);
FD_SET(request_sock, &set);
maxfd = request_sock;
while() {
rset = set;
timeout.tv_sec = ;
timeout.tv_usec = ;
if((nfound = select(maxfd + , &rset, (fd_set *), (fd_set *), &timeout)) < )
{
perror("select");
return -;
}
else
if (nfound == )
{
printf("."); fflush(stdout);
continue;
}
if (FD_ISSET(request_sock, &rset))
{
addrlen = sizeof(remote);
if ((new_sock = accept(request_sock, (struct sockaddr *)&remote, &addrlen)) < )
{
perror("accept");
return -;
}
printf("connection from host %s, port %d, socket %d\r\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port),
new_sock);
FD_SET(new_sock, &set);
if (new_sock > maxfd)
maxfd = new_sock;
FD_CLR(request_sock, &rset);
nfound --;
}
for (fd=; fd <= maxfd && nfound > ; fd++) {
if (FD_ISSET(fd, &rset)) {
nfound --;
if ((bytesread = read(fd, buf, sizeof buf - ))<)
{
perror("read");
}
if (bytesread == )
{
fprintf(stderr, "server: end of file on %d\r\n",fd);
FD_CLR(fd, &set);
close(fd);
continue;
}
buf[bytesread] = ;
printf("%s: %d bytes from %d: %s\n", argv[], bytesread, fd, buf);
if (write(fd, buf, bytesread) < )
{
perror("echo");
FD_CLR(fd, &set);
close(fd);
}
}
}
}
return ;
}
 //client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h> #define RET_OK 0
#define RET_ERR -1
#define LISTEN_QUEUE_NUM 5
#define BUFFER_SIZE 256
#define ECHO_PORT 2029 int main(int argc, char **argv)
{
int sock, maxfd = ;
struct sockaddr_in servaddr;
struct hostent *server;
fd_set rset, set;
int nfound, bytesread;
char buf[BUFFER_SIZE]; if (argc < )
{
fprintf(stderr,"usage %s hostname\n", argv[]);
return RET_ERR;
}
if((server = gethostbyname(argv[])) == NULL)
{
herror("gethostbyname. ");
return RET_ERR;
}
if ((sock = socket(AF_INET, SOCK_STREAM, )) < )
{
perror("socket");
return -;
}
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = *(uint32_t *)server->h_addr;
servaddr.sin_port = htons((uint16_t)ECHO_PORT);
if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < )
{
perror("connect");
return -;
}
maxfd = fileno(stdin);
FD_ZERO(&set);
FD_SET(sock, &set);
FD_SET(maxfd, &set);
maxfd = (maxfd > sock ? maxfd : sock) + ;
while()
{
rset = set;
if ((nfound = select(maxfd, &rset, (fd_set *), (fd_set *), NULL)) < )
{
if (errno == EINTR) {
fprintf(stderr, "interrupted system call\n");
continue;
}
perror("select");
exit();
}
if (FD_ISSET(fileno(stdin), &rset)) {
if (fgets(buf, sizeof(buf), stdin) == NULL) {
if (ferror(stdin)) {
perror("stdin");
return -;
}
return ;
}
if (write(sock, buf, strlen(buf)) < )
{
perror("write");
return -;
}
}
if (FD_ISSET(sock,&rset)) {
if((bytesread = read(sock, buf, sizeof buf)) < )
{
perror("read");
exit();
}
else
if(bytesread == )
{
fprintf(stderr, "server disconnect\n");
exit();
}
buf[bytesread] = ;
printf("%s\n",buf);
}
}
return ;
}
 #Makefile
PROGRAM_CLIENT = client
PROGRAM_SERVER = server CC = gcc LDPATH = /usr/local/lib INCLUDEDIR = . SOURCE_PATH = . OPTS = -g -Wall -I. -I$(INCLUDEDIR) CFLAGS = $(OPTS) -fPIC LIBS = -L./ -L$(LDPATH) all: $(PROGRAM_SERVER) $(PROGRAM_CLIENT) clean:
rm -f *.o *.core *.bak $(PROGRAM_CLIENT) $(PROGRAM_SERVER) *.a core.* *.exe $(PROGRAM_CLIENT): $(LIBRARY) $(SOURCE_PATH)/client.c
$(CC) $(CFLAGS) $(SOURCE_PATH)/client.c $(LIBS) -o $(PROGRAM_CLIENT) $(OBJS) -Wl,-rpath,./ $(PROGRAM_SERVER): $(LIBRARY) $(SOURCE_PATH)/server.c
$(CC) $(CFLAGS) $(SOURCE_PATH)/server.c $(LIBS) -o $(PROGRAM_SERVER) $(OBJS) -Wl,-rpath,./

poll模型

 //server.c
#include <unistd.h>
#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */ #include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h> #include <poll.h> /* poll function */
#include <limits.h> #define MAXLINE 10240 #ifndef OPEN_MAX
#define OPEN_MAX 40960
#endif void handle(struct pollfd* clients, int maxClient, int readyClient); int main(int argc, char **argv)
{
int servPort = ;
int listenq = ;
int listenfd, connfd;
struct pollfd clients[OPEN_MAX];
int maxi;
socklen_t socklen = sizeof(struct sockaddr_in);
struct sockaddr_in cliaddr, servaddr;
char buf[MAXLINE];
int nready; bzero(&servaddr, socklen);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(servPort); listenfd = socket(AF_INET, SOCK_STREAM, );
if (listenfd < ) {
perror("socket error");
} int opt = ;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < ) {
perror("setsockopt error");
} if(bind(listenfd, (struct sockaddr *) &servaddr, socklen) == -) {
perror("bind error");
exit(-);
}
if (listen(listenfd, listenq) < ) {
perror("listen error");
} clients[].fd = listenfd;
clients[].events = POLLIN;
int i;
for (i = ; i< OPEN_MAX; i++)
clients[i].fd = -;
maxi = listenfd + ; printf("pollechoserver startup, listen on port:%d\n", servPort);
printf("max connection is %d\n", OPEN_MAX); for ( ; ; ) {
nready = poll(clients, maxi + , -);
//printf("nready is %d\n", nready);
if (nready == -) {
perror("poll error");
}
if (clients[].revents & POLLIN) {
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &socklen);
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf(buf, ""); for (i = ; i < OPEN_MAX; i++) {
if (clients[i].fd == -) {
clients[i].fd = connfd;
clients[i].events = POLLIN;
break;
}
} if (i == OPEN_MAX) {
fprintf(stderr, "too many connection, more than %d\n", OPEN_MAX);
close(connfd);
continue;
} if (i > maxi)
maxi = i; --nready;
} handle(clients, maxi, nready);
}
} void handle(struct pollfd* clients, int maxClient, int nready) {
int connfd;
int i, nread;
char buf[MAXLINE]; if (nready == )
return; for (i = ; i< maxClient; i++) {
connfd = clients[i].fd;
if (connfd == -)
continue;
if (clients[i].revents & (POLLIN | POLLERR)) {
nread = read(connfd, buf, MAXLINE);//读取客户端socket流
if (nread < ) {
perror("read error");
close(connfd);
clients[i].fd = -;
continue;
}
if (nread == ) {
printf("client close the connection");
close(connfd);
clients[i].fd = -;
continue;
} write(connfd, buf, nread);//响应客户端
if (--nready <= )//没有连接需要处理,退出循环
break;
}
}
}

epoll模型

 #include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <iostream>
using namespace std;
#define MAX_EVENTS 500
struct myevent_s
{
int fd;
void (*call_back)(int fd, int events, void *arg);
int events;
void *arg;
int status; // 1: in epoll wait list, 0 not in
char buff[]; // recv data buffer
int len;
long last_active; // last active time
};
// set event
void EventSet(myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg)
{
ev->fd = fd;
ev->call_back = call_back;
ev->events = ;
ev->arg = arg;
ev->status = ;
ev->last_active = time(NULL);
}
// add/mod an event to epoll
void EventAdd(int epollFd, int events, myevent_s *ev)
{
struct epoll_event epv = {, {}};
int op;
epv.data.ptr = ev;
epv.events = ev->events = events;
if(ev->status == ){
op = EPOLL_CTL_MOD;
}
else{
op = EPOLL_CTL_ADD;
ev->status = ;
}
if(epoll_ctl(epollFd, op, ev->fd, &epv) < )
printf("Event Add failed[fd=%d]\n", ev->fd);
else
printf("Event Add OK[fd=%d]\n", ev->fd);
}
// delete an event from epoll
void EventDel(int epollFd, myevent_s *ev)
{
struct epoll_event epv = {, {}};
if(ev->status != ) return;
epv.data.ptr = ev;
ev->status = ;
epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv);
}
int g_epollFd;
myevent_s g_Events[MAX_EVENTS+]; // g_Events[MAX_EVENTS] is used by listen fd
void RecvData(int fd, int events, void *arg);
void SendData(int fd, int events, void *arg);
// accept new connections from clients
void AcceptConn(int fd, int events, void *arg)
{
struct sockaddr_in sin;
socklen_t len = sizeof(struct sockaddr_in);
int nfd, i;
// accept
if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -)
{
if(errno != EAGAIN && errno != EINTR)
{
printf("%s: bad accept", __func__);
}
return;
}
do
{
for(i = ; i < MAX_EVENTS; i++)
{
if(g_Events[i].status == )
{
break;
}
}
if(i == MAX_EVENTS)
{
printf("%s:max connection limit[%d].", __func__, MAX_EVENTS);
break;
}
// set nonblocking
if(fcntl(nfd, F_SETFL, O_NONBLOCK) < ) break;
// add a read event for receive data
EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]);
EventAdd(g_epollFd, EPOLLIN|EPOLLET, &g_Events[i]);
printf("new conn[%s:%d][time:%d]\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), g_Events[i].last_active);
}while();
}
// receive data
void RecvData(int fd, int events, void *arg)
{
struct myevent_s *ev = (struct myevent_s*)arg;
int len;
// receive data
len = recv(fd, ev->buff, sizeof(ev->buff)-, );
EventDel(g_epollFd, ev);
if(len > )
{
ev->len = len;
ev->buff[len] = '\0';
printf("C[%d]:%s\n", fd, ev->buff);
// change to send event
EventSet(ev, fd, SendData, ev);
EventAdd(g_epollFd, EPOLLOUT|EPOLLET, ev);
}
else if(len == )
{
close(ev->fd);
printf("[fd=%d] closed gracefully.\n", fd);
}
else
{
close(ev->fd);
printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
}
}
// send data
void SendData(int fd, int events, void *arg)
{
struct myevent_s *ev = (struct myevent_s*)arg;
int len;
// send data
len = send(fd, ev->buff, ev->len, );
ev->len = ;
EventDel(g_epollFd, ev);
if(len > )
{
// change to receive event
EventSet(ev, fd, RecvData, ev);
EventAdd(g_epollFd, EPOLLIN|EPOLLET, ev);
}
else
{
close(ev->fd);
printf("recv[fd=%d] error[%d]\n", fd, errno);
}
}
void InitListenSocket(int epollFd, short port)
{
int listenFd = socket(AF_INET, SOCK_STREAM, );
fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking
printf("server listen fd=%d\n", listenFd);
EventSet(&g_Events[MAX_EVENTS], listenFd, AcceptConn, &g_Events[MAX_EVENTS]);
// add listen socket
EventAdd(epollFd, EPOLLIN|EPOLLET, &g_Events[MAX_EVENTS]);
// bind & listen
sockaddr_in sin;
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
bind(listenFd, (const sockaddr*)&sin, sizeof(sin));
listen(listenFd, );
}
int main(int argc, char **argv)
{
short port = ; // default port
if(argc == ){
port = atoi(argv[]);
}
// create epoll
g_epollFd = epoll_create(MAX_EVENTS);
if(g_epollFd <= ) printf("create epoll failed.%d\n", g_epollFd);
// create & bind listen socket, and add to epoll, set non-blocking
InitListenSocket(g_epollFd, port);
// event loop
struct epoll_event events[MAX_EVENTS];
printf("server running:port[%d]\n", port);
int checkPos = ;
while(){
// a simple timeout check here, every time 100, better to use a mini-heap, and add timer event
long now = time(NULL);
for(int i = ; i < ; i++, checkPos++) // doesn't check listen fd
{
if(checkPos == MAX_EVENTS) checkPos = ; // recycle
if(g_Events[checkPos].status != ) continue;
long duration = now - g_Events[checkPos].last_active;
if(duration >= ) // 60s timeout
{
close(g_Events[checkPos].fd);
printf("[fd=%d] timeout[%d--%d].\n", g_Events[checkPos].fd, g_Events[checkPos].last_active, now);
EventDel(g_epollFd, &g_Events[checkPos]);
}
}
// wait for events to happen
int fds = epoll_wait(g_epollFd, events, MAX_EVENTS, );
if(fds < ){
printf("epoll_wait error, exit\n");
break;
}
for(int i = ; i < fds; i++){
myevent_s *ev = (struct myevent_s*)events[i].data.ptr;
if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event
{
ev->call_back(ev->fd, events[i].events, ev->arg);
}
if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event
{
ev->call_back(ev->fd, events[i].events, ev->arg);
}
}
}
// free resource
return ;
}

参考:

Linux/Unix IO多路复用之系列