epoll实现的回显服务器

服务器端实现:

  1 /*************************************************************************
  2     > File Name: epoll.c
  3     > Created Time: Fri 13 Mar 2015 10:22:19 PM CST
  4  ************************************************************************/
  5 #include "utils.h"
  6 #include <sys/epoll.h>
  7 #include <fcntl.h>
  8 
  9 #define CN 100
 10 
 11 void setnonblocking (int fd)
 12 {
 13     int op = fcntl(fd, F_GETFL);
 14     if (op < 0)
 15     {
 16         print_error(__func__, __LINE__, strerror(errno));
 17         exit(EXIT_FAILURE);
 18     }
 19 
 20     op = op | O_NONBLOCK;
 21 
 22     if (fcntl(fd, F_SETFL, op) < 0)
 23     {
 24         print_error(__func__, __LINE__, strerror(errno));
 25         exit(EXIT_FAILURE);
 26     }
 27 }
 28 
 29 int socket_create (int port)
 30 {
 31     int sk = socket(AF_INET, SOCK_STREAM, 0);
 32     if (sk == -1)
 33     {
 34         print_error(__func__, __LINE__, strerror(errno));
 35         return -1;
 36     }
 37 
 38     int on = 1;
 39     if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
 40     {
 41         print_error(__func__, __LINE__, strerror(errno));
 42         return -1;
 43     }
 44 
 45     struct sockaddr_in addr;
 46     memset(&addr, 0, sizeof(addr));
 47     addr.sin_family = AF_INET;
 48     addr.sin_port = htons(port);
 49     addr.sin_addr.s_addr = htonl(INADDR_ANY);
 50 
 51     if (bind(sk, (struct sockaddr*)&addr, sizeof(addr)) == -1)
 52     {
 53         print_error(__func__, __LINE__, strerror(errno));
 54         return -1;
 55     }
 56     
 57     if (listen(sk, 20) == -1)
 58     {
 59         print_error(__func__, __LINE__, strerror(errno));
 60         return -1;
 61     }
 62 
 63     return sk;
 64 }
 65 
 66 int socket_accept (int listen_sk)
 67 {
 68     struct sockaddr_in peeraddr;
 69     memset(&peeraddr, 0, sizeof(peeraddr));
 70     socklen_t len = sizeof(peeraddr);
 71     int sk;
 72     if ((sk = accept(listen_sk, (struct sockaddr*)&peeraddr, &len)) == -1)
 73     {
 74         print_error(__func__, __LINE__, strerror(errno));
 75         return -1;
 76     }
 77 
 78     return sk;
 79 }
 80 
 81 
 82 int socket_recv (int sk)
 83 {
 84     char buf[BUFSIZE];
 85     memset(buf, 0, BUFSIZE);
 86 
 87     int sz;
 88     if ((sz = recv(sk, buf, BUFSIZE, 0)) <= 0)
 89     {
 90         print_error(__func__, __LINE__, strerror(errno));
 91         return -1;
 92     }
 93 
 94     fprintf(stdout, "%s\n", buf);
 95     if (send(sk, buf, sz, 0) <= 0)
 96     {
 97         print_error(__func__, __LINE__, strerror(errno));
 98         return -1;
 99     }
100 
101     return 0;
102 }
103 
104 int main (int argv, char** argc)
105 {
106     if (argv < 2)
107         return EXIT_FAILURE;
108 
109     int listen_sk = socket_create(atoi(argc[1]));
110     if (listen_sk == -1)
111     {
112         print_error(__func__, __LINE__, strerror(errno));
113         close(listen_sk);
114         exit(EXIT_FAILURE);
115     }
116     
117     struct epoll_event ev, events[CN];
118     int epfd = epoll_create(CN);
119 
120     setnonblocking(listen_sk);
121 
122     ev.data.fd = listen_sk;
123     ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
124     epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sk, &ev);
125 
126     int sk;
127     for (;;)
128     {
129         int nfd = epoll_wait(epfd, events, CN, -1);
130         if (nfd == -1)
131         {
132             print_error(__func__, __LINE__, strerror(errno));
133             break;
134         }
135         int i;
136         for (i = 0; i < nfd; i++)
137         {
138             if (events[i].data.fd < 0)
139             continue;
140 
141             if (events[i].data.fd == listen_sk)
142             {
143                if ((sk = socket_accept(listen_sk)) ==-1)
144                 {
145                     print_error(__func__, __LINE__, strerror(errno));
146                     break;
147                 }
148                 setnonblocking(sk);
149                 ev.data.fd = sk;
150                 ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
151                 
152                 if (epoll_ctl(epfd, EPOLL_CTL_ADD, sk, &ev) == -1)
153                 {
154                     print_error(__func__, __LINE__, strerror(errno));
155                     break;
156                 }
157 
158                 continue;
159             }
160 
161             if (events[i].events & EPOLLIN)
162             {
163                 sk = events[i].data.fd;
164                 if (socket_recv(sk) == -1)
165                 {
166                     close(sk);
167                     events[i].data.fd = -1;
168                 }
169             }
170     
171             if (events[i].events & EPOLLERR)
172             {
173                 close(events[i].data.fd);
174                 events[i].data.fd = -1;
175             }
176 
177             if (events[i].events & EPOLLHUP)
178             {
179                 close(events[i].data.fd);
180                 events[i].data.fd = -1;
181             }
182         }
183     }
184 
185     close(epfd);
186     return EXIT_SUCCESS;
187 }

客户端实现:

 1 /*************************************************************************
 2     > File Name: echoclt.c
 3     > Created Time: Thu 12 Mar 2015 01:15:54 PM CST
 4  ************************************************************************/
 5 #include "utils.h"
 6 #include <sys/time.h>
 7 #include <sys/select.h>
 8 
 9 void echoclt (const char* ip, const int port)
10 {
11     int sk;
12     if ((sk = socket(AF_INET, SOCK_STREAM, 0)) == -1)
13     {
14         print_error(__func__, __LINE__, strerror(errno));
15         goto end;
16     }
17 
18     struct sockaddr_in saddr;
19     memset(&saddr, 0, sizeof(saddr));
20     saddr.sin_family = AF_INET;
21     saddr.sin_port = htons(port);
22     saddr.sin_addr.s_addr = inet_addr(ip);
23 
24     if (connect(sk, (struct sockaddr*)&saddr, sizeof(saddr)) == -1)
25     {
26         print_error(__func__, __LINE__, strerror(errno));
27         goto end;
28     }
29 
30     char buf[BUFSIZE];
31     //int sz;
32 
33     fd_set rset;
34     FD_ZERO(&rset);
35 
36     int fn = fileno(stdin);
37     int nr, max;
38     if (sk > fn )
39         max = sk;
40     else
41         max = fn;
42 
43     for (;;)
44     {
45        
46         FD_SET(sk, &rset);
47         FD_SET(fn, &rset);
48         if ((nr = select(max + 1, &rset, NULL, NULL, NULL)) == -1)
49         {
50             goto end;
51         }
52         if (FD_ISSET(fn, &rset))
53         {
54             memset(buf, 0, BUFSIZE);
55             if (fgets(buf, BUFSIZE, stdin) == NULL)
56             {
57                 print_error(__func__, __LINE__, strerror(errno));
58                 goto end;
59             }
60         
61         
62             if (send(sk, buf, strlen(buf), 0) <= 0)
63             {
64                 print_error(__func__, __LINE__, strerror(errno));
65                 goto end;
66             }
67         }
68         if (FD_ISSET(sk, &rset))
69         {
70             memset(buf, 0, BUFSIZE);
71             if (recv(sk, buf, BUFSIZE, 0) <= 0)
72             {
73                 print_error(__func__, __LINE__, strerror(errno));
74                 goto end;
75             }
76             fprintf(stdout, "%s", buf);
77         }
78     }
79 end:
80     if (sk)
81         close(sk);
82 }
83 int main (int argv, char** argc)
84 {
85     if (argv <3)
86     {
87         print_error(__func__, __LINE__, NULL);
88         return EXIT_FAILURE;
89     }
90 
91     echoclt(argc[1], atoi(argc[2]));
92     return EXIT_SUCCESS;
93 }

 

posted on 2015-03-14 19:56  子墨sky  阅读(95)  评论(0)    收藏  举报

导航