Linux下测试代码:
TCP模型
1 //TCPClient.c 2 #include<string.h> 3 #includein .h> 4 #include5 #include 6 #include 7 #define MYPORT 4000 8 #define BACKLOG 10 9 #define MAX_LEN 100 10 11 int main(void) 12 { 13 int sockfd; 14 int tmp_int; 15 char *msg_send = NULL; 16 char *msg_recv = NULL; 17 int sin_size; 18 int len,bytes_sent,bytes_recv; 19 struct sockaddr_in my_addr; 20 struct sockaddr_in dest_addr; 21 22 sockfd=socket(AF_INET,SOCK_STREAM,0); 23 my_addr.sin_family=AF_INET; 24 my_addr.sin_port=htons(MYPORT); 25 my_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); 26 bzero(&(my_addr.sin_zero),8); 27 tmp_int = connect(sockfd,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr)); 28 if( tmp_int < 0 ) 29 { 30 printf("ERROR:connect erro %s!\n", strerror(errno)); 31 close(sockfd); 32 return -1; 33 } 34 msg_send="This is TCPClient!\n"; 35 len=strlen(msg_send); 36 bytes_sent=send(sockfd,msg_send,len,0); 37 while( len != bytes_sent ) 38 { 39 tmp_int = bytes_sent; 40 len -= bytes_sent; 41 printf("send %d,%d packet!\n", bytes_sent,len); 42 bytes_sent = send( sockfd, msg_send+tmp_int, len, 0 ); 43 } 44 msg_recv = (char *)malloc( MAX_LEN ); 45 if( NULL == msg_recv ) 46 { 47 printf("ERROR:malloc mem error!\n"); 48 close(sockfd); 49 return -1; 50 } 51 memset(msg_recv, 0, MAX_LEN ); 52 bytes_recv=recv(sockfd,msg_recv,MAX_LEN,0); 53 if( bytes_recv >0 ) 54 { 55 printf("recv: %s\n!", msg_recv ); 56 } 57 else 58 { 59 printf("ERROR:net error\n"); 60 } 61 close(sockfd); 62 return 0; 63 }
1 //TCPServer.c 2 #include<string.h> 3 #include4 #include in .h> 5 #include6 #include 7 #define MYPORT 4000 8 #define BACKLOG 10 9 #define MAX_LEN 100 10 11 int main(void) 12 { 13 int sockfd; 14 char* msg_send; 15 char* msg_recv; 16 int sin_size; 17 int new_fd; 18 int tmp_int; 19 int len,bytes_sent,bytes_recv; 20 struct sockaddr_in my_addr; 21 struct sockaddr_in their_addr; 22 23 sockfd=socket(AF_INET,SOCK_STREAM,0); 24 my_addr.sin_family=AF_INET; 25 my_addr.sin_port=htons(MYPORT); 26 my_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); 27 bzero(&(my_addr.sin_zero),8); 28 bind(sockfd,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr)); 29 listen(sockfd,BACKLOG); 30 sin_size=sizeof(struct sockaddr_in); 31 new_fd=accept(sockfd,(struct sockaddr *)&their_addr, &sin_size); 32 msg_send="This is TCPServer!\n"; 33 len=strlen(msg_send); 34 bytes_sent=send(new_fd,msg_send,len,0); 35 while( len != bytes_sent ) 36 { 37 tmp_int = bytes_sent; 38 len -= bytes_sent; 39 printf("send %d packet\n", bytes_sent); 40 bytes_sent = send( new_fd, msg_send+tmp_int, len, 0 ); 41 } 42 msg_recv = (char *)malloc( MAX_LEN ); 43 if( NULL == msg_recv ) 44 { 45 printf("ERROR:malloc mem error!\n"); 46 close(new_fd); 47 return -1; 48 } 49 memset(msg_recv, 0, MAX_LEN ); 50 bytes_recv=recv(new_fd,msg_recv,MAX_LEN,0); 51 if( bytes_recv >0 ) 52 { 53 printf("recv: %s\n", msg_recv ); 54 } 55 else 56 { 57 printf("ERROR:net error!\n"); 58 } 59 close(new_fd); 60 close(sockfd); 61 return 0; 62 }
UDP模型
1 //UDPServer.c 2 #include3 #include 4 #include 5 #include in .h> 6 #include7 #include 8 #include <string.h> 9 #include 10 #include 11 #include 12 #include 13 #include 14 15 #define RET_OK 0 16 #define RET_ERR -1 17 #define LISTEN_QUEUE_NUM 5 18 #define BUFFER_SIZE 256 19 #define ECHO_PORT 2029 20 21 int main(int argc, char **argv) 22 { 23 int sockfd, len, opt = 1; 24 struct sockaddr_in cliaddr; 25 uint8_t buffer[BUFFER_SIZE]; 26 int ret = RET_OK; 27 28 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 29 { 30 perror("ERROR: opening socket!"); 31 return RET_ERR; 32 } 33 if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0) 34 { 35 perror("ERROR: set sockopt!"); 36 close(sockfd); 37 return 0; 38 } 39 memset(&cliaddr, 0, sizeof(cliaddr)); 40 cliaddr.sin_family = AF_INET; 41 cliaddr.sin_addr.s_addr = INADDR_ANY; 42 cliaddr.sin_port = htons(ECHO_PORT); 43 if ((ret = bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))) < 0) 44 { 45 perror("ERROR: on binding"); 46 goto failed; 47 } 48 49 do 50 { 51 len = sizeof(cliaddr); 52 if((ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len)) > 0) 53 { 54 printf("Recv from %s\r\n", inet_ntoa(cliaddr.sin_addr)); 55 ret = sendto(sockfd, buffer, ret, 0, (struct sockaddr *)&cliaddr, len); 56 } 57 }while(ret >= 0); 58 59 close(sockfd); 60 return 0; 61 }
1 //UDPClient.c 2 #include3 #include 4 #include 5 #include in .h> 6 #include7 #include 8 #include <string.h> 9 #include 10 #include 11 #include 12 #include 13 #include 14 15 #define RET_OK 0 16 #define RET_ERR -1 17 #define LISTEN_QUEUE_NUM 5 18 #define BUFFER_SIZE 256 19 #define ECHO_PORT 2029 20 21 int main(int argc, char *argv[]) 22 { 23 int sockfd, ret = RET_OK; 24 struct sockaddr_in servaddr; 25 struct hostent *server; 26 char buffer[BUFFER_SIZE]; 27 28 if (argc < 2) { 29 fprintf(stderr,"ERROR: usage %s hostname\n", argv[0]); 30 return RET_ERR; 31 } 32 if((server = gethostbyname(argv[1])) == NULL) 33 { 34 herror("ERROR: get host by name. "); 35 return RET_ERR; 36 } 37 38 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 39 { 40 perror("ERROR: opening socket"); 41 return RET_ERR; 42 } 43 memset(&servaddr, 0, sizeof(servaddr)); 44 servaddr.sin_family = AF_INET; 45 servaddr.sin_addr.s_addr = *(uint32_t *)server->h_addr; 46 servaddr.sin_port = htons((uint16_t)ECHO_PORT); 47 48 while(1) 49 { 50 printf("Enter the message : "); 51 if(fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) 52 { 53 break; 54 } 55 if((ret = sendto(sockfd, buffer ,strlen(buffer), 0, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0) 56 { 57 perror("ERROR: writing to socket"); 58 break; 59 } 60 if((ret = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, NULL, NULL)) < 0) 61 { 62 perror("ERROR: reading from socket"); 63 break; 64 } 65 buffer[ret] = 0; 66 printf("Server echo message: %s\n",buffer); 67 } 68 close(sockfd); 69 return ret < 0 ? RET_ERR : RET_OK; 70 }
1 #Makefile 2 3 PROGRAM_CLIENT = client 4 PROGRAM_SERVER = server 5 6 CC = gcc 7 8 LDPATH = /usr/local/lib 9 10 INCLUDEDIR = . 11 12 SOURCE_PATH = . 13 14 OPTS = -g -Wall -I. -I$(INCLUDEDIR) 15 16 CFLAGS = $(OPTS) -fPIC 17 18 LIBS = -L./ -L$(LDPATH) 19 20 all: $(PROGRAM_SERVER) $(PROGRAM_CLIENT) 21 22 clean: 23 rm -f *.o *.core *.bak $(PROGRAM_CLIENT) $(PROGRAM_SERVER) *.a core.* *.exe 24 25 $(PROGRAM_CLIENT): $(LIBRARY) $(SOURCE_PATH)/client.c 26 $(CC) $(CFLAGS) $(SOURCE_PATH)/client.c $(LIBS) -o $(PROGRAM_CLIENT) $(OBJS) -Wl,-rpath,./ 27 28 $(PROGRAM_SERVER): $(LIBRARY) $(SOURCE_PATH)/server.c 29 $(CC) $(CFLAGS) $(SOURCE_PATH)/server.c $(LIBS) -o $(PROGRAM_SERVER) $(OBJS) -Wl,-rpath,./
select模型
1 //server.c 2 #include.h> 3 #include 8 #include4 #include 5 #include 6 #include 7 #include in .h>9 #include 10 #include 11 #include 12 #include 13 #include 14 #include <string.h> 15 #include select .h> 16 #include17 18 #define LISTEN_QUEUE_NUM 5 19 #define BUFFER_SIZE 256 20 #define ECHO_PORT 2029 21 22 int main(int argc, char **argv) 23 { 24 struct sockaddr_in servaddr, remote; 25 int request_sock, new_sock; 26 int nfound, fd, maxfd, bytesread; 27 uint32_t addrlen; 28 fd_set rset, set; 29 struct timeval timeout; 30 char buf[BUFFER_SIZE]; 31 32 if ((request_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 33 perror("socket"); 34 return -1; 35 } 36 memset(&servaddr, 0, sizeof(servaddr)); 37 servaddr.sin_family = AF_INET; 38 servaddr.sin_addr.s_addr = INADDR_ANY; 39 servaddr.sin_port = htons((uint16_t)ECHO_PORT); 40 41 if (bind(request_sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) 42 { 43 perror("bind"); 44 return -1; 45 } 46 if (listen(request_sock, LISTEN_QUEUE_NUM) < 0) 47 { 48 perror("listen"); 49 return -1; 50 } 51 52 FD_ZERO(&set); 53 FD_SET(request_sock, &set); 54 maxfd = request_sock; 55 while(1) { 56 rset = set; 57 timeout.tv_sec = 0; 58 timeout.tv_usec = 500000; 59 if((nfound = select(maxfd + 1, &rset, (fd_set *)0, (fd_set *)0, &timeout)) < 0) 60 { 61 perror("select"); 62 return -1; 63 } 64 else 65 if (nfound == 0) 66 { 67 printf("."); fflush(stdout); 68 continue; 69 } 70 if (FD_ISSET(request_sock, &rset)) 71 { 72 addrlen = sizeof(remote); 73 if ((new_sock = accept(request_sock, (struct sockaddr *)&remote, &addrlen)) < 0) 74 { 75 perror("accept"); 76 return -1; 77 } 78 printf("connection from host %s, port %d, socket %d\r\n", 79 inet_ntoa(remote.sin_addr), ntohs(remote.sin_port), 80 new_sock); 81 FD_SET(new_sock, &set); 82 if (new_sock > maxfd) 83 maxfd = new_sock; 84 FD_CLR(request_sock, &rset); 85 nfound --; 86 } 87 for (fd=0; fd <= maxfd && nfound > 0; fd++) { 88 if (FD_ISSET(fd, &rset)) { 89 nfound --; 90 if ((bytesread = read(fd, buf, sizeof buf - 1))<0) 91 { 92 perror("read"); 93 } 94 if (bytesread == 0) 95 { 96 fprintf(stderr, "server: end of file on %d\r\n",fd); 97 FD_CLR(fd, &set); 98 close(fd); 99 continue; 100 } 101 buf[bytesread] = 0; 102 printf("%s: %d bytes from %d: %s\n", argv[0], bytesread, fd, buf); 103 if (write(fd, buf, bytesread) < 0) 104 { 105 perror("echo"); 106 FD_CLR(fd, &set); 107 close(fd); 108 } 109 } 110 } 111 } 112 return 0; 113 }
1 //client.c 2 #include3 #include 4 #include 5 #include in .h> 6 #include7 #include 8 #include 9 #include 10 #include <string.h> 11 #include 12 #include 13 #include select .h> 14 15 16 #define RET_OK 0 17 #define RET_ERR -1 18 #define LISTEN_QUEUE_NUM 5 19 #define BUFFER_SIZE 256 20 #define ECHO_PORT 2029 21 22 int main(int argc, char **argv) 23 { 24 int sock, maxfd = 0; 25 struct sockaddr_in servaddr; 26 struct hostent *server; 27 fd_set rset, set; 28 int nfound, bytesread; 29 char buf[BUFFER_SIZE]; 30 31 if (argc < 2) 32 { 33 fprintf(stderr,"usage %s hostname\n", argv[0]); 34 return RET_ERR; 35 } 36 if((server = gethostbyname(argv[1])) == NULL) 37 { 38 herror("gethostbyname. "); 39 return RET_ERR; 40 } 41 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 42 { 43 perror("socket"); 44 return -1; 45 } 46 memset(&servaddr, 0, sizeof(servaddr)); 47 servaddr.sin_family = AF_INET; 48 servaddr.sin_addr.s_addr = *(uint32_t *)server->h_addr; 49 servaddr.sin_port = htons((uint16_t)ECHO_PORT); 50 if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) 51 { 52 perror("connect"); 53 return -1; 54 } 55 maxfd = fileno(stdin); 56 FD_ZERO(&set); 57 FD_SET(sock, &set); 58 FD_SET(maxfd, &set); 59 maxfd = (maxfd > sock ? maxfd : sock) + 1; 60 while(1) 61 { 62 rset = set; 63 if ((nfound = select(maxfd, &rset, (fd_set *)0, (fd_set *)0, NULL)) < 0) 64 { 65 if (errno == EINTR) { 66 fprintf(stderr, "interrupted system call\n"); 67 continue; 68 } 69 perror("select"); 70 exit(1); 71 } 72 if (FD_ISSET(fileno(stdin), &rset)) { 73 if (fgets(buf, sizeof(buf), stdin) == NULL) { 74 if (ferror(stdin)) { 75 perror("stdin"); 76 return -1; 77 } 78 return 0; 79 } 80 if (write(sock, buf, strlen(buf)) < 0) 81 { 82 perror("write"); 83 return -1; 84 } 85 } 86 if (FD_ISSET(sock,&rset)) { 87 if((bytesread = read(sock, buf, sizeof buf)) < 0) 88 { 89 perror("read"); 90 exit(1); 91 } 92 else 93 if(bytesread == 0) 94 { 95 fprintf(stderr, "server disconnect\n"); 96 exit(0); 97 } 98 buf[bytesread] = 0; 99 printf("%s\n",buf); 100 } 101 } 102 return 0; 103 }
1 #Makefile 2 PROGRAM_CLIENT = client 3 PROGRAM_SERVER = server 4 5 CC = gcc 6 7 LDPATH = /usr/local/lib 8 9 INCLUDEDIR = . 10 11 SOURCE_PATH = . 12 13 OPTS = -g -Wall -I. -I$(INCLUDEDIR) 14 15 CFLAGS = $(OPTS) -fPIC 16 17 LIBS = -L./ -L$(LDPATH) 18 19 all: $(PROGRAM_SERVER) $(PROGRAM_CLIENT) 20 21 clean: 22 rm -f *.o *.core *.bak $(PROGRAM_CLIENT) $(PROGRAM_SERVER) *.a core.* *.exe 23 24 $(PROGRAM_CLIENT): $(LIBRARY) $(SOURCE_PATH)/client.c 25 $(CC) $(CFLAGS) $(SOURCE_PATH)/client.c $(LIBS) -o $(PROGRAM_CLIENT) $(OBJS) -Wl,-rpath,./ 26 27 $(PROGRAM_SERVER): $(LIBRARY) $(SOURCE_PATH)/server.c 28 $(CC) $(CFLAGS) $(SOURCE_PATH)/server.c $(LIBS) -o $(PROGRAM_SERVER) $(OBJS) -Wl,-rpath,./
poll模型
1 //server.c 2 #include3 #include /* basic system data types */ 4 #include/* basic socket definitions */ 5 #includein .h> /* sockaddr_in{} and other Internet defns */ 6 #include/* inet(3) functions */ 7 8 #include9 #include 10 #include 11 #include <string.h> 12 13 14 #include /* poll function */ 15 #include16 17 #define MAXLINE 10240 18 19 #ifndef OPEN_MAX 20 #define OPEN_MAX 40960 21 #endif 22 23 void handle(struct pollfd* clients, int maxClient, int readyClient); 24 25 int main(int argc, char **argv) 26 { 27 int servPort = 6888; 28 int listenq = 1024; 29 int listenfd, connfd; 30 struct pollfd clients[OPEN_MAX]; 31 int maxi; 32 socklen_t socklen = sizeof(struct sockaddr_in); 33 struct sockaddr_in cliaddr, servaddr; 34 char buf[MAXLINE]; 35 int nready; 36 37 bzero(&servaddr, socklen); 38 servaddr.sin_family = AF_INET; 39 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 40 servaddr.sin_port = htons(servPort); 41 42 listenfd = socket(AF_INET, SOCK_STREAM, 0); 43 if (listenfd < 0) { 44 perror("socket error"); 45 } 46 47 int opt = 1; 48 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { 49 perror("setsockopt error"); 50 } 51 52 if(bind(listenfd, (struct sockaddr *) &servaddr, socklen) == -1) { 53 perror("bind error"); 54 exit(-1); 55 } 56 if (listen(listenfd, listenq) < 0) { 57 perror("listen error"); 58 } 59 60 clients[0].fd = listenfd; 61 clients[0].events = POLLIN; 62 int i; 63 for (i = 1; i< OPEN_MAX; i++) 64 clients[i].fd = -1; 65 maxi = listenfd + 1; 66 67 printf("pollechoserver startup, listen on port:%d\n", servPort); 68 printf("max connection is %d\n", OPEN_MAX); 69 70 for ( ; ; ) { 71 nready = poll(clients, maxi + 1, -1); 72 //printf("nready is %d\n", nready); 73 if (nready == -1) { 74 perror("poll error"); 75 } 76 if (clients[0].revents & POLLIN) { 77 connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &socklen); 78 sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); 79 printf(buf, ""); 80 81 for (i = 0; i < OPEN_MAX; i++) { 82 if (clients[i].fd == -1) { 83 clients[i].fd = connfd; 84 clients[i].events = POLLIN; 85 break; 86 } 87 } 88 89 if (i == OPEN_MAX) { 90 fprintf(stderr, "too many connection, more than %d\n", OPEN_MAX); 91 close(connfd); 92 continue; 93 } 94 95 if (i > maxi) 96 maxi = i; 97 98 --nready; 99 } 100 101 handle(clients, maxi, nready); 102 } 103 } 104 105 void handle(struct pollfd* clients, int maxClient, int nready) { 106 int connfd; 107 int i, nread; 108 char buf[MAXLINE]; 109 110 if (nready == 0) 111 return; 112 113 for (i = 1; i< maxClient; i++) { 114 connfd = clients[i].fd; 115 if (connfd == -1) 116 continue; 117 if (clients[i].revents & (POLLIN | POLLERR)) { 118 nread = read(connfd, buf, MAXLINE);//读取客户端socket流 119 if (nread < 0) { 120 perror("read error"); 121 close(connfd); 122 clients[i].fd = -1; 123 continue; 124 } 125 if (nread == 0) { 126 printf("client close the connection"); 127 close(connfd); 128 clients[i].fd = -1; 129 continue; 130 } 131 132 write(connfd, buf, nread);//响应客户端 133 if (--nready <= 0)//没有连接需要处理,退出循环 134 break; 135 } 136 } 137 }
epoll模型
1 #include
2 #include
3 #include in .h>
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 using namespace std;
11 #define MAX_EVENTS 500
12 struct myevent_s
13 {
14 int fd;
15 void (*call_back)(int fd, int events, void *arg);
16 int events;
17 void *arg;
18 int status; // 1: in epoll wait list, 0 not in
19 char buff[128]; // recv data buffer
20 int len;
21 long last_active; // last active time
22 };
23 // set event
24 void EventSet(myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg)
25 {
26 ev->fd = fd;
27 ev->call_back = call_back;
28 ev->events = 0;
29 ev->arg = arg;
30 ev->status = 0;
31 ev->last_active = time(NULL);
32 }
33 // add/mod an event to epoll
34 void EventAdd(int epollFd, int events, myevent_s *ev)
35 {
36 struct epoll_event epv = {0, {0}};
37 int op;
38 epv.data.ptr = ev;
39 epv.events = ev->events = events;
40 if(ev->status == 1){
41 op = EPOLL_CTL_MOD;
42 }
43 else{
44 op = EPOLL_CTL_ADD;
45 ev->status = 1;
46 }
47 if(epoll_ctl(epollFd, op, ev->fd, &epv) < 0)
48 printf("Event Add failed[fd=%d]\n", ev->fd);
49 else
50 printf("Event Add OK[fd=%d]\n", ev->fd);
51 }
52 // delete an event from epoll
53 void EventDel(int epollFd, myevent_s *ev)
54 {
55 struct epoll_event epv = {0, {0}};
56 if(ev->status != 1) return;
57 epv.data.ptr = ev;
58 ev->status = 0;
59 epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv);
60 }
61 int g_epollFd;
62 myevent_s g_Events[MAX_EVENTS+1]; // g_Events[MAX_EVENTS] is used by listen fd
63 void RecvData(int fd, int events, void *arg);
64 void SendData(int fd, int events, void *arg);
65 // accept new connections from clients
66 void AcceptConn(int fd, int events, void *arg)
67 {
68 struct sockaddr_in sin;
69 socklen_t len = sizeof(struct sockaddr_in);
70 int nfd, i;
71 // accept
72 if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1)
73 {
74 if(errno != EAGAIN && errno != EINTR)
75 {
76 printf("%s: bad accept", __func__);
77 }
78 return;
79 }
80 do
81 {
82 for(i = 0; i < MAX_EVENTS; i++)
83 {
84 if(g_Events[i].status == 0)
85 {
86 break;
87 }
88 }
89 if(i == MAX_EVENTS)
90 {
91 printf("%s:max connection limit[%d].", __func__, MAX_EVENTS);
92 break;
93 }
94 // set nonblocking
95 if(fcntl(nfd, F_SETFL, O_NONBLOCK) < 0) break;
96 // add a read event for receive data
97 EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]);
98 EventAdd(g_epollFd, EPOLLIN|EPOLLET, &g_Events[i]);
99 printf("new conn[%s:%d][time:%d]\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), g_Events[i].last_active);
100 }while(0);
101 }
102 // receive data
103 void RecvData(int fd, int events, void *arg)
104 {
105 struct myevent_s *ev = (struct myevent_s*)arg;
106 int len;
107 // receive data
108 len = recv(fd, ev->buff, sizeof(ev->buff)-1, 0);
109 EventDel(g_epollFd, ev);
110 if(len > 0)
111 {
112 ev->len = len;
113 ev->buff[len] = '\0';
114 printf("C[%d]:%s\n", fd, ev->buff);
115 // change to send event
116 EventSet(ev, fd, SendData, ev);
117 EventAdd(g_epollFd, EPOLLOUT|EPOLLET, ev);
118 }
119 else if(len == 0)
120 {
121 close(ev->fd);
122 printf("[fd=%d] closed gracefully.\n", fd);
123 }
124 else
125 {
126 close(ev->fd);
127 printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
128 }
129 }
130 // send data
131 void SendData(int fd, int events, void *arg)
132 {
133 struct myevent_s *ev = (struct myevent_s*)arg;
134 int len;
135 // send data
136 len = send(fd, ev->buff, ev->len, 0);
137 ev->len = 0;
138 EventDel(g_epollFd, ev);
139 if(len > 0)
140 {
141 // change to receive event
142 EventSet(ev, fd, RecvData, ev);
143 EventAdd(g_epollFd, EPOLLIN|EPOLLET, ev);
144 }
145 else
146 {
147 close(ev->fd);
148 printf("recv[fd=%d] error[%d]\n", fd, errno);
149 }
150 }
151 void InitListenSocket(int epollFd, short port)
152 {
153 int listenFd = socket(AF_INET, SOCK_STREAM, 0);
154 fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking
155 printf("server listen fd=%d\n", listenFd);
156 EventSet(&g_Events[MAX_EVENTS], listenFd, AcceptConn, &g_Events[MAX_EVENTS]);
157 // add listen socket
158 EventAdd(epollFd, EPOLLIN|EPOLLET, &g_Events[MAX_EVENTS]);
159 // bind & listen
160 sockaddr_in sin;
161 bzero(&sin, sizeof(sin));
162 sin.sin_family = AF_INET;
163 sin.sin_addr.s_addr = INADDR_ANY;
164 sin.sin_port = htons(port);
165 bind(listenFd, (const sockaddr*)&sin, sizeof(sin));
166 listen(listenFd, 5);
167 }
168 int main(int argc, char **argv)
169 {
170 short port = 12345; // default port
171 if(argc == 2){
172 port = atoi(argv[1]);
173 }
174 // create epoll
175 g_epollFd = epoll_create(MAX_EVENTS);
176 if(g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd);
177 // create & bind listen socket, and add to epoll, set non-blocking
178 InitListenSocket(g_epollFd, port);
179 // event loop
180 struct epoll_event events[MAX_EVENTS];
181 printf("server running:port[%d]\n", port);
182 int checkPos = 0;
183 while(1){
184 // a simple timeout check here, every time 100, better to use a mini-heap, and add timer event
185 long now = time(NULL);
186 for(int i = 0; i < 100; i++, checkPos++) // doesn't check listen fd
187 {
188 if(checkPos == MAX_EVENTS) checkPos = 0; // recycle
189 if(g_Events[checkPos].status != 1) continue;
190 long duration = now - g_Events[checkPos].last_active;
191 if(duration >= 60) // 60s timeout
192 {
193 close(g_Events[checkPos].fd);
194 printf("[fd=%d] timeout[%d--%d].\n", g_Events[checkPos].fd, g_Events[checkPos].last_active, now);
195 EventDel(g_epollFd, &g_Events[checkPos]);
196 }
197 }
198 // wait for events to happen
199 int fds = epoll_wait(g_epollFd, events, MAX_EVENTS, 1000);
200 if(fds < 0){
201 printf("epoll_wait error, exit\n");
202 break;
203 }
204 for(int i = 0; i < fds; i++){
205 myevent_s *ev = (struct myevent_s*)events[i].data.ptr;
206 if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event
207 {
208 ev->call_back(ev->fd, events[i].events, ev->arg);
209 }
210 if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event
211 {
212 ev->call_back(ev->fd, events[i].events, ev->arg);
213 }
214 }
215 }
216 // free resource
217 return 0;
218 }
http://www.cnblogs.com/iTsihang/archive/2013/05/23/3095775.html