Chinaunix首页 | 论坛 | 博客
  • 博客访问: 349267
  • 博文数量: 63
  • 博客积分: 1412
  • 博客等级: 中尉
  • 技术积分: 648
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-10 23:07
文章分类

全部博文(63)

文章存档

2012年(42)

2011年(21)

我的朋友

分类: C/C++

2012-04-05 20:52:54

利用libevent编写服务端程序,主要有3部分
//创建主通知链base
1.base = event_base_new();
 
//创建要监听的事件,并将其加入到主通知链中。
2.listener_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base);
  event_add(listener_event, NULL);
  event_free( listener_event ); 释放由event_new申请的结构体
 
//主循环
3.event_base_dispatch(base)
 
相关网址:
以下为参考文档网址
 
 
下面的代码转自

下面程序重点:
因为do_read, do_write是异步的,所以下面的程序使用了state这个结构体变量将do_read和do_write联系起来。 解决了异步之间的问题。

点击(此处)折叠或打开

  1. /* For sockaddr_in */
  2. #include <netinet/in.h>
  3. /* For socket functions */
  4. #include <sys/socket.h>
  5. /* For fcntl */
  6. #include <fcntl.h>

  7. #include <event2/event.h>

  8. #include <assert.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <errno.h>

  14. #define MAX_LINE 16384
  15. #define PORT 9999

  16. void do_read(evutil_socket_t fd, short events, void *arg);
  17. void do_write(evutil_socket_t fd, short events, void *arg);

  18. struct fd_state
  19. {
  20.     char buffer[MAX_LINE];
  21.     size_t buffer_used;

  22.     size_t n_written;
  23.     size_t write_upto;

  24.     struct event *read_event;
  25.     struct event *write_event;
  26. };

  27. struct fd_state *
  28. alloc_fd_state(struct event_base *base, evutil_socket_t fd)
  29. {
  30.     struct fd_state *state = (struct fd_state *)malloc(sizeof(struct fd_state));
  31.     if (!state)
  32.     {
  33.         return NULL;
  34.     }

  35.     state->read_event = event_new(base, fd, EV_READ|EV_PERSIST, do_read, state);
  36.     if (!state->read_event)
  37.     {
  38.         free(state);
  39.         return NULL;
  40.     }

  41.     state->write_event =
  42.     event_new(base, fd, EV_WRITE|EV_PERSIST, do_write, state);
  43.     if (!state->write_event)
  44.     {
  45.         event_free(state->read_event);
  46.         free(state);
  47.         return NULL;
  48.     }

  49.     assert(state->write_event);

  50.     return state;
  51. }

  52. void
  53. free_fd_state(struct fd_state *state)
  54. {
  55.     event_free(state->read_event);
  56.     event_free(state->write_event);
  57.     free(state);
  58. }

  59. void
  60. do_read(evutil_socket_t fd, short events, void *arg)
  61. {
  62.     struct fd_state *state = arg;
  63.     char buf[1024];
  64.     int i;
  65.     ssize_t result;
  66.     while (1)
  67.     {
  68. //        assert(state->write_event);
  69.         result = recv(fd, buf, sizeof(buf), 0);
  70.         if (result <= 0)
  71.             break;
  72.         printf( "[%s][%d]buf=[%s]len=[%d]\n", __FILE__, __LINE__, buf, result );
  73.     }

  74.     memcpy( state->buffer, "reply", sizeof("reply") );
  75.     assert(state->write_event);
  76.     event_add(state->write_event, NULL);
  77.     state->write_upto = state->buffer_used;

  78.     if (result == 0)
  79.     {
  80.         free_fd_state(state);
  81.     }
  82.     else if (result < 0)
  83.     {
  84.         if (errno == EAGAIN) // XXXX use evutil macro
  85.         return;
  86.         perror("recv");
  87.         free_fd_state(state);
  88.     }
  89. }





  90. void
  91. do_write(evutil_socket_t fd, short events, void *arg)
  92. {
  93.     struct fd_state *state = arg;

  94.     printf( "[%d]\n", __LINE__ );
  95. //    while (state->n_written < state->write_upto)
  96.     {
  97. //        ssize_t result = send(fd, state->buffer + state->n_written,
  98. //             state->write_upto - state->n_written, 0);
  99.         ssize_t result = send(fd, state->buffer, strlen(state->buffer), 0 );
  100.         if (result < 0)
  101.         {
  102.             if (errno == EAGAIN) // XXX use evutil macro
  103.                 return;
  104.             free_fd_state(state);
  105.                 return;
  106.         }
  107.         assert(result != 0);

  108.         state->n_written += result;
  109.     }

  110. //    if (state->n_written == state->buffer_used)
  111.     {
  112.         state->n_written = state->write_upto = state->buffer_used = 1;
  113.     }

  114.     event_del(state->write_event);
  115. }

  116. void
  117. do_accept(evutil_socket_t listener, short event, void *arg)
  118. {
  119.     struct event_base *base = arg;
  120.     struct sockaddr_storage ss;
  121.     socklen_t slen = sizeof(ss);

  122.     int fd = accept(listener, (struct sockaddr*)&ss, &slen);
  123.     if (fd < 0)
  124.     { // XXXX eagain??
  125.         perror("accept");
  126.     }
  127.     else if (fd > FD_SETSIZE)
  128.     {
  129.         close(fd); // XXX replace all closes with EVUTIL_CLOSESOCKET */
  130.     }
  131.     else
  132.     {
  133.         struct fd_state *state;
  134.         evutil_make_socket_nonblocking(fd);
  135.         state = alloc_fd_state(base, fd);

  136.         assert(state); /*XXX err*/
  137.         assert(state->write_event);
  138.         event_add(state->read_event, NULL);
  139.     }
  140. }

  141. void
  142. run(void)
  143. {
  144.     evutil_socket_t listener;
  145.     struct sockaddr_in sin;
  146.     struct event_base *base;
  147.     struct event *listener_event;

  148.     base = event_base_new();
  149.     if (!base)
  150.     return; /*XXXerr*/

  151.     sin.sin_family = AF_INET;
  152.     sin.sin_addr.s_addr = 0;
  153.     sin.sin_port = htons(PORT);

  154.     listener = socket(AF_INET, SOCK_STREAM, 0);
  155.     evutil_make_socket_nonblocking(listener);

  156.     #ifndef WIN32
  157.     {
  158.         int one = 1;
  159.         setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  160.     }
  161.     #endif

  162.     if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
  163.         perror("bind");
  164.         return;
  165.     }

  166.     if (listen(listener, 16)<0) {
  167.         perror("listen");
  168.         return;
  169.     }

  170.     //do_accept(evutil_socket_t listener, short event, void *arg)
  171.     listener_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base);
  172.     /*XXX check it */
  173.     event_add(listener_event, NULL);

  174.     event_base_dispatch(base);
  175. }

  176. int
  177. main(int c, char **v)
  178. {
  179.     setvbuf(stdout, NULL, _IONBF, 0);

  180.     run();
  181.     return 0;
  182. }

阅读(7433) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~