epoll测试

server

  1 #include <sys/socket.h>
  2 #include <sys/epoll.h>
  3 #include <netinet/in.h>
  4 #include <arpa/inet.h>
  5 #include <fcntl.h>
  6 #include <unistd.h>
  7 #include <errno.h>
  8 #include <iostream>
  9 #include <cstring>
 10 #include <cstdlib>
 11 
 12 using namespace std;
 13 
 14 #define MAX_EVENTS 1000
 15 
 16 struct RP_EVENT_S
 17 {
 18    int fd;
 19    void (*call_back)(int fd, int events, void* args);
 20    int events;
 21    void* args;
 22    int status; // 1 in epoll wait list, 0 not in 
 23    char buff[128];
 24    int len, s_offset;
 25    long last_active;
 26 };
 27 
 28 void EventSet(RP_EVENT_S* ev, int fd, void (*call_back)(int, int, void*), void* arg)
 29 {
 30    ev->fd = fd;
 31    ev->call_back = call_back;
 32    ev->args = arg;
 33    ev->status = 0;
 34    bzero(ev->buff, sizeof(ev->buff));
 35    ev->s_offset = 0;
 36    ev->len = 0;
 37    ev->last_active = time(NULL);
 38 }
 39 
 40 void EventAdd(int epoll_fd, int events, RP_EVENT_S* ev)
 41 {
 42    struct epoll_event epv = {0, {0}};
 43    int op;
 44    epv.data.ptr = ev;
 45    epv.events = ev->events = events;
 46 
 47    if (1 == ev->status)
 48    {
 49       op = EPOLL_CTL_MOD;
 50    }
 51    else {
 52       op = EPOLL_CTL_ADD;
 53       ev->status = 1;
 54    }
 55 
 56    if (epoll_ctl(epoll_fd, op, ev->fd, &epv) < 0)
 57    {
 58       std::cerr << "Event Add Failed [fd = " << ev->fd << "], events = " << events << std::endl;
 59    }
 60    else
 61    {
 62    //   std::cout << "Event Add OK [fd = " << ev->fd << "], events = " << events << std::endl;
 63    }
 64 }
 65 
 66 void EventDel(int epoll_fd, RP_EVENT_S* ev)
 67 {
 68    struct epoll_event epv = {0, {0}};
 69    if (1 != ev->status)
 70    {
 71       return;
 72    }
 73    epv.data.ptr = ev;
 74    ev->status = 0;
 75    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ev->fd, &epv);
 76 }
 77 
 78 int g_epoll_fd;
 79 RP_EVENT_S g_Events[MAX_EVENTS + 1];
 80 
 81 void RecvData(int fd, int events, void* args);
 82 void SendData(int fd, int events, void* args);
 83 
 84 void AcceptConn(int fd, int events, void* args)
 85 {
 86    struct sockaddr_in sin;
 87    socklen_t len = sizeof(sin);
 88 
 89    int nfd, i;
 90    if ((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1)
 91    {
 92       if (EAGAIN != errno && EINTR != errno)
 93       {
 94 
 95       }
 96       std::cerr << __func__ << ": accept error. " << errno << std::endl;
 97       return;
 98    }
 99    
100    do
101    {
102       
103       for (i=0;i<MAX_EVENTS;++i)
104       {
105          if (g_Events[i].status == 0)
106          {
107             break ;
108          }
109       }
110       std::cout << "connection: " << i << std::endl;
111 
112       if (MAX_EVENTS == i)
113       {
114          std::cerr << __func__ << ": Max connection limit. LIMIT = " << MAX_EVENTS << std::endl;
115          break ;
116       }
117 
118       int iret = 0;
119       if ((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0)
120       {
121          std::cerr << __func__ << ": fcntl nonblocking failed: " << iret << std::endl;
122          break ;
123       }
124 
125       EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]);
126       EventAdd(g_epoll_fd, EPOLLIN, &g_Events[i]);
127    }
128    while (0);
129 
130 //   std::cout << "new connection [" << inet_ntoa(sin.sin_addr) << ":" << ntohs(sin.sin_port) << 
131 //      "], pos = " << i << std::endl;
132 }
133 
134 void RecvData(int fd, int events, void* args)
135 {
136    struct RP_EVENT_S* ev = (struct RP_EVENT_S*)args;
137    const char* str = "Hello world";
138    int len = 0;
139    len = recv(fd, ev->buff+ev->len, sizeof(ev->buff) - 1 - ev->len, 0);
140    EventDel(g_epoll_fd, ev);
141 
142    if (len > 0)
143    {
144       ev->len += len;
145 //      ev->buff[ev->len] = '\0';
146 //      std::cout << "C[" << fd << "]:" << ev->buff << std::endl;
147       //EventSet(ev, fd, SendData, ev);
148       //memcpy((void*)str, ev->buff, strlen(str));
149       //ev->len = strlen(str);
150       ev->call_back = SendData;
151       EventAdd(g_epoll_fd, EPOLLOUT, ev);
152    }
153    else if (0 == len)
154    {
155       close(ev->fd);
156 //      std::cout << "[fd=" << fd << "] , closed gracefully." << std::endl;
157    }
158    else
159    {
160       close(ev->fd);
161       std::cerr << "recv[fd=" << fd << "] error[" << errno << "]: " << strerror(errno) << std::endl;
162    }
163 }
164 
165 
166 void SendData(int fd, int events, void* args)
167 {
168    struct RP_EVENT_S* ev = (struct RP_EVENT_S*)args;
169 
170    int len;
171    len = send(fd, ev->buff + ev->s_offset, ev->len - ev->s_offset, 0);
172 
173    if (len > 0)
174    {
175    //   std::cout << "send[fd=" << fd << "], [" << len << "<->" << ev->len, ev->buff;
176       ev->s_offset += len;
177       if (ev->s_offset == ev->len)
178       {
179          EventDel(g_epoll_fd, ev);
180          EventSet(ev, fd, RecvData, ev);
181          EventAdd(g_epoll_fd, EPOLLIN, ev);
182       }
183    }
184    else
185    {
186       close(ev->fd);
187       EventDel(g_epoll_fd, ev);
188       std::cerr << "Send[fd=" << fd << "] errno[" << errno << "]" << std::endl;
189    }
190 }
191 
192 void InitListenSocket(int epoll_fd, short port)
193 {
194    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
195    fcntl(listen_fd, F_SETFL, O_NONBLOCK);
196    std::cout << "server listen fd = " << listen_fd << std::endl;
197    EventSet(&g_Events[MAX_EVENTS], listen_fd, AcceptConn, &g_Events[MAX_EVENTS]);
198 
199    EventAdd(epoll_fd, EPOLLIN, &g_Events[MAX_EVENTS]);
200 
201    sockaddr_in sin;
202    bzero(&sin, sizeof(sin));
203 
204    sin.sin_family = AF_INET;
205    sin.sin_addr.s_addr = INADDR_ANY;
206    sin.sin_port = htons(port);
207    bind(listen_fd, (const sockaddr*)&sin, sizeof(sin));
208    listen(listen_fd, 5);
209 }
210 
211 int main(int argc, char *argv[])
212 {
213    unsigned short port = 12345;
214    if (2 == argc)
215    {
216       port = atoi(argv[1]);
217    }
218 
219    g_epoll_fd = epoll_create(MAX_EVENTS);
220    if (0 >= g_epoll_fd)
221    {
222       std::cerr << "create epoll failed." << std::endl;
223       return -1;
224    }
225 
226    InitListenSocket(g_epoll_fd, port);
227 
228    struct epoll_event events[MAX_EVENTS];
229 
230    int check_pos = 0;
231    while (1)
232    {
233       long now = time(NULL);
234       for (int i=0;i<100;++i, check_pos++)
235       {
236          if (check_pos == MAX_EVENTS) check_pos = 0;
237             
238          if (g_Events[check_pos].status != 1)
239          {
240             continue ;
241          }
242 
243          long duration = now - g_Events[check_pos].last_active;
244 
245          if (duration >= 60)
246          {
247             close(g_Events[check_pos].fd);
248             std::cout << "[fd=" << g_Events[check_pos].fd << "] timeout"  << std::endl;
249             EventDel(g_epoll_fd, &g_Events[check_pos]);
250          }
251       }
252 
253       int fds = epoll_wait(g_epoll_fd, events, MAX_EVENTS, 1000);
254       if (fds < 0)
255       {
256          std::cerr << "epoll wait error. exit" << std::endl;
257          break;
258       }
259 
260       for (int i=0;i<fds;++i)
261       {
262          RP_EVENT_S* ev = (struct RP_EVENT_S*)events[i].data.ptr;
263          if ((events[i].events & EPOLLIN) && (ev->events & EPOLLIN) )
264          {
265             ev->call_back(ev->fd, events[i].events, ev->args);
266          }
267          if ((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT) )
268          {
269             ev->call_back(ev->fd, events[i].events, ev->args);
270          }
271       }
272    }
273    return 0; 
274 }

client

 1 -module(client).
 2 -export([start/0, start/1]).
 3 
 4 start() ->
 5     test("127.0.0.1", 12345, "Hello world").
 6 
 7 start(N) ->
 8     tests_spawn("127.0.0.1", 12345, "Hello world", N).
 9 
10 
11 loop_send_recv(Socket, Str) ->
12     ok = gen_tcp:send(Socket, term_to_binary(Str)),
13     receive
14         {tcp, Socket, Bin} ->
15         %io:format("client reveived binary = ~p~n", [Bin]),
16         Val = binary_to_term(Bin),
17         if 
18             Val /= Str ->
19                 io:format("recv error ~p~n", [Val]);
20             true ->
21                 TEMP = 1
22         end
23         %io:format("client result=~p~n", [Val])
24         %gen_tcp:close(Socket) 
25     end,
26     loop_send_recv(Socket, Str).
27 
28 test(Ip, Port, Str) ->
29     {ok, Socket} = gen_tcp:connect(Ip, Port, [binary, {packet, 4}]),
30     loop_send_recv(Socket, Str).
31     
32 
33 tests_spawn(Ip, Port, Str, 1) ->
34     spawn(fun() -> test(Ip, Port, Str) end);
35 tests_spawn(Ip, Port, Str, N) ->
36     spawn(fun() -> test(Ip, Port, Str) end),
37     tests_spawn(Ip, Port, Str, N-1).

 

posted @ 2014-04-03 01:13  vinsonliudk  阅读(318)  评论(0编辑  收藏  举报