zoukankan      html  css  js  c++  java
  • [z]Libevent使用例子,从简单到复杂

    [z]http://blog.csdn.net/luotuo44/article/details/39670221

            本文从简单到复杂,展示如何使用libevent。网上的许多例子都是只有服务器端的,本文里面客户端和服务器端都有,以飨读者。

            关于libevent编程时的一些疑问可以阅读《libevent编程疑难解答》。假如读者还想了解libevent的具体实现,可以阅读《libevent源码分析》系统文章。

            不说这么多了,直接上代码。

            

    初等:

    客户端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include<sys/types.h>  
    2. #include<sys/socket.h>  
    3. #include<netinet/in.h>  
    4. #include<arpa/inet.h>  
    5. #include<errno.h>  
    6. #include<unistd.h>  
    7.   
    8. #include<stdio.h>  
    9. #include<string.h>  
    10. #include<stdlib.h>  
    11.   
    12. #include<event.h>  
    13. #include<event2/util.h>  
    14.   
    15.   
    16.   
    17.   
    18. int tcp_connect_server(const char* server_ip, int port);  
    19.   
    20.   
    21. void cmd_msg_cb(int fd, short events, void* arg);  
    22. void socket_read_cb(int fd, short events, void *arg);  
    23.   
    24. int main(int argc, char** argv)  
    25. {  
    26.     if( argc < 3 )  
    27.     {  
    28.         printf("please input 2 parameter ");  
    29.         return -1;  
    30.     }  
    31.   
    32.   
    33.     //两个参数依次是服务器端的IP地址、端口号  
    34.     int sockfd = tcp_connect_server(argv[1], atoi(argv[2]));  
    35.     if( sockfd == -1)  
    36.     {  
    37.         perror("tcp_connect error ");  
    38.         return -1;  
    39.     }  
    40.   
    41.     printf("connect to server successful ");  
    42.   
    43.     struct event_base* base = event_base_new();  
    44.   
    45.     struct event *ev_sockfd = event_new(base, sockfd,  
    46.                                         EV_READ | EV_PERSIST,  
    47.                                         socket_read_cb, NULL);  
    48.     event_add(ev_sockfd, NULL);  
    49.   
    50.     //监听终端输入事件  
    51.     struct event* ev_cmd = event_new(base, STDIN_FILENO,  
    52.                                       EV_READ | EV_PERSIST, cmd_msg_cb,  
    53.                                       (void*)&sockfd);  
    54.   
    55.   
    56.     event_add(ev_cmd, NULL);  
    57.   
    58.     event_base_dispatch(base);  
    59.   
    60.     printf("finished  ");  
    61.     return 0;  
    62. }  
    63.   
    64.   
    65.   
    66.   
    67.   
    68.   
    69. void cmd_msg_cb(int fd, short events, void* arg)  
    70. {  
    71.     char msg[1024];  
    72.   
    73.     int ret = read(fd, msg, sizeof(msg));  
    74.     if( ret <= 0 )  
    75.     {  
    76.         perror("read fail ");  
    77.         exit(1);  
    78.     }  
    79.   
    80.     int sockfd = *((int*)arg);  
    81.   
    82.     //把终端的消息发送给服务器端  
    83.     //为了简单起见,不考虑写一半数据的情况  
    84.     write(sockfd, msg, ret);  
    85. }  
    86.   
    87.   
    88. void socket_read_cb(int fd, short events, void *arg)  
    89. {  
    90.     char msg[1024];  
    91.   
    92.     //为了简单起见,不考虑读一半数据的情况  
    93.     int len = read(fd, msg, sizeof(msg)-1);  
    94.     if( len <= 0 )  
    95.     {  
    96.         perror("read fail ");  
    97.         exit(1);  
    98.     }  
    99.   
    100.     msg[len] = '';  
    101.   
    102.     printf("recv %s from server ", msg);  
    103. }  
    104.   
    105.   
    106.   
    107. typedef struct sockaddr SA;  
    108. int tcp_connect_server(const char* server_ip, int port)  
    109. {  
    110.     int sockfd, status, save_errno;  
    111.     struct sockaddr_in server_addr;  
    112.   
    113.     memset(&server_addr, 0, sizeof(server_addr) );  
    114.   
    115.     server_addr.sin_family = AF_INET;  
    116.     server_addr.sin_port = htons(port);  
    117.     status = inet_aton(server_ip, &server_addr.sin_addr);  
    118.   
    119.     if( status == 0 ) //the server_ip is not valid value  
    120.     {  
    121.         errno = EINVAL;  
    122.         return -1;  
    123.     }  
    124.   
    125.     sockfd = ::socket(PF_INET, SOCK_STREAM, 0);  
    126.     if( sockfd == -1 )  
    127.         return sockfd;  
    128.   
    129.   
    130.     status = ::connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );  
    131.   
    132.     if( status == -1 )  
    133.     {  
    134.         save_errno = errno;  
    135.         ::close(sockfd);  
    136.         errno = save_errno; //the close may be error  
    137.         return -1;  
    138.     }  
    139.   
    140.     evutil_make_socket_nonblocking(sockfd);  
    141.   
    142.     return sockfd;  
    143. }  

    服务器端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include<stdio.h>  
    2. #include<string.h>  
    3. #include<errno.h>  
    4.   
    5. #include<unistd.h>  
    6. #include<event.h>  
    7.   
    8.   
    9.   
    10. void accept_cb(int fd, short events, void* arg);  
    11. void socket_read_cb(int fd, short events, void *arg);  
    12.   
    13. int tcp_server_init(int port, int listen_num);  
    14.   
    15. int main(int argc, char** argv)  
    16. {  
    17.   
    18.     int listener = tcp_server_init(9999, 10);  
    19.     if( listener == -1 )  
    20.     {  
    21.         perror(" tcp_server_init error ");  
    22.         return -1;  
    23.     }  
    24.   
    25.     struct event_base* base = event_base_new();  
    26.   
    27.     //添加监听客户端请求连接事件  
    28.     struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST,  
    29.                                         accept_cb, base);  
    30.     event_add(ev_listen, NULL);  
    31.   
    32.   
    33.     event_base_dispatch(base);  
    34.   
    35.     return 0;  
    36. }  
    37.   
    38.   
    39.   
    40. void accept_cb(int fd, short events, void* arg)  
    41. {  
    42.     evutil_socket_t sockfd;  
    43.   
    44.     struct sockaddr_in client;  
    45.     socklen_t len = sizeof(client);  
    46.   
    47.     sockfd = ::accept(fd, (struct sockaddr*)&client, &len );  
    48.     evutil_make_socket_nonblocking(sockfd);  
    49.   
    50.     printf("accept a client %d ", sockfd);  
    51.   
    52.     struct event_base* base = (event_base*)arg;  
    53.   
    54.     //仅仅是为了动态创建一个event结构体  
    55.     struct event *ev = event_new(NULL, -1, 0, NULL, NULL);  
    56.     //将动态创建的结构体作为event的回调参数  
    57.     event_assign(ev, base, sockfd, EV_READ | EV_PERSIST,  
    58.                  socket_read_cb, (void*)ev);  
    59.   
    60.     event_add(ev, NULL);  
    61. }  
    62.   
    63.   
    64. void socket_read_cb(int fd, short events, void *arg)  
    65. {  
    66.     char msg[4096];  
    67.     struct event *ev = (struct event*)arg;  
    68.     int len = read(fd, msg, sizeof(msg) - 1);  
    69.   
    70.   
    71.   
    72.     if( len <= 0 )  
    73.     {  
    74.         printf("some error happen when read ");  
    75.         event_free(ev);  
    76.         close(fd);  
    77.         return ;  
    78.     }  
    79.   
    80.     msg[len] = '';  
    81.     printf("recv the client msg: %s", msg);  
    82.   
    83.     char reply_msg[4096] = "I have recvieced the msg: ";  
    84.     strcat(reply_msg + strlen(reply_msg), msg);  
    85.   
    86.     write(fd, reply_msg, strlen(reply_msg) );  
    87. }  
    88.   
    89.   
    90.   
    91. typedef struct sockaddr SA;  
    92. int tcp_server_init(int port, int listen_num)  
    93. {  
    94.     int errno_save;  
    95.     evutil_socket_t listener;  
    96.   
    97.     listener = ::socket(AF_INET, SOCK_STREAM, 0);  
    98.     if( listener == -1 )  
    99.         return -1;  
    100.   
    101.     //允许多次绑定同一个地址。要用在socket和bind之间  
    102.     evutil_make_listen_socket_reuseable(listener);  
    103.   
    104.     struct sockaddr_in sin;  
    105.     sin.sin_family = AF_INET;  
    106.     sin.sin_addr.s_addr = 0;  
    107.     sin.sin_port = htons(port);  
    108.   
    109.     if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )  
    110.         goto error;  
    111.   
    112.     if( ::listen(listener, listen_num) < 0)  
    113.         goto error;  
    114.   
    115.   
    116.     //跨平台统一接口,将套接字设置为非阻塞状态  
    117.     evutil_make_socket_nonblocking(listener);  
    118.   
    119.     return listener;  
    120.   
    121.     error:  
    122.         errno_save = errno;  
    123.         evutil_closesocket(listener);  
    124.         errno = errno_save;  
    125.   
    126.         return -1;  
    127. }  

    中等:

    客户端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include<sys/types.h>  
    2. #include<sys/socket.h>  
    3. #include<netinet/in.h>  
    4. #include<arpa/inet.h>  
    5. #include<errno.h>  
    6. #include<unistd.h>  
    7.   
    8. #include<stdio.h>  
    9. #include<string.h>  
    10. #include<stdlib.h>  
    11.   
    12. #include<event.h>  
    13. #include<event2/bufferevent.h>  
    14. #include<event2/buffer.h>  
    15. #include<event2/util.h>  
    16.   
    17.   
    18.   
    19.   
    20. int tcp_connect_server(const char* server_ip, int port);  
    21.   
    22.   
    23. void cmd_msg_cb(int fd, short events, void* arg);  
    24. void server_msg_cb(struct bufferevent* bev, void* arg);  
    25. void event_cb(struct bufferevent *bev, short event, void *arg);  
    26.   
    27. int main(int argc, char** argv)  
    28. {  
    29.     if( argc < 3 )  
    30.     {  
    31.         printf("please input 2 parameter ");  
    32.         return -1;  
    33.     }  
    34.   
    35.   
    36.     //两个参数依次是服务器端的IP地址、端口号  
    37.     int sockfd = tcp_connect_server(argv[1], atoi(argv[2]));  
    38.     if( sockfd == -1)  
    39.     {  
    40.         perror("tcp_connect error ");  
    41.         return -1;  
    42.     }  
    43.   
    44.     printf("connect to server successful ");  
    45.   
    46.     struct event_base* base = event_base_new();  
    47.   
    48.     struct bufferevent* bev = bufferevent_socket_new(base, sockfd,  
    49.                                                      BEV_OPT_CLOSE_ON_FREE);  
    50.   
    51.     //监听终端输入事件  
    52.     struct event* ev_cmd = event_new(base, STDIN_FILENO,  
    53.                                       EV_READ | EV_PERSIST, cmd_msg_cb,  
    54.                                       (void*)bev);  
    55.     event_add(ev_cmd, NULL);  
    56.   
    57.     //当socket关闭时会用到回调参数  
    58.     bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void*)ev_cmd);  
    59.     bufferevent_enable(bev, EV_READ | EV_PERSIST);  
    60.   
    61.   
    62.     event_base_dispatch(base);  
    63.   
    64.     printf("finished  ");  
    65.     return 0;  
    66. }  
    67.   
    68.   
    69.   
    70.   
    71.   
    72.   
    73. void cmd_msg_cb(int fd, short events, void* arg)  
    74. {  
    75.     char msg[1024];  
    76.   
    77.     int ret = read(fd, msg, sizeof(msg));  
    78.     if( ret < 0 )  
    79.     {  
    80.         perror("read fail ");  
    81.         exit(1);  
    82.     }  
    83.   
    84.     struct bufferevent* bev = (struct bufferevent*)arg;  
    85.   
    86.     //把终端的消息发送给服务器端  
    87.     bufferevent_write(bev, msg, ret);  
    88. }  
    89.   
    90.   
    91. void server_msg_cb(struct bufferevent* bev, void* arg)  
    92. {  
    93.     char msg[1024];  
    94.   
    95.     size_t len = bufferevent_read(bev, msg, sizeof(msg));  
    96.     msg[len] = '';  
    97.   
    98.     printf("recv %s from server ", msg);  
    99. }  
    100.   
    101.   
    102. void event_cb(struct bufferevent *bev, short event, void *arg)  
    103. {  
    104.   
    105.     if (event & BEV_EVENT_EOF)  
    106.         printf("connection closed ");  
    107.     else if (event & BEV_EVENT_ERROR)  
    108.         printf("some other error ");  
    109.   
    110.     //这将自动close套接字和free读写缓冲区  
    111.     bufferevent_free(bev);  
    112.   
    113.     struct event *ev = (struct event*)arg;  
    114.     //因为socket已经没有,所以这个event也没有存在的必要了  
    115.     event_free(ev);  
    116. }  
    117.   
    118.   
    119. typedef struct sockaddr SA;  
    120. int tcp_connect_server(const char* server_ip, int port)  
    121. {  
    122.     int sockfd, status, save_errno;  
    123.     struct sockaddr_in server_addr;  
    124.   
    125.     memset(&server_addr, 0, sizeof(server_addr) );  
    126.   
    127.     server_addr.sin_family = AF_INET;  
    128.     server_addr.sin_port = htons(port);  
    129.     status = inet_aton(server_ip, &server_addr.sin_addr);  
    130.   
    131.     if( status == 0 ) //the server_ip is not valid value  
    132.     {  
    133.         errno = EINVAL;  
    134.         return -1;  
    135.     }  
    136.   
    137.     sockfd = ::socket(PF_INET, SOCK_STREAM, 0);  
    138.     if( sockfd == -1 )  
    139.         return sockfd;  
    140.   
    141.   
    142.     status = ::connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );  
    143.   
    144.     if( status == -1 )  
    145.     {  
    146.         save_errno = errno;  
    147.         ::close(sockfd);  
    148.         errno = save_errno; //the close may be error  
    149.         return -1;  
    150.     }  
    151.   
    152.     evutil_make_socket_nonblocking(sockfd);  
    153.   
    154.     return sockfd;  
    155. }  

    服务器端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include<stdio.h>  
    2. #include<string.h>  
    3. #include<errno.h>  
    4.   
    5. #include<event.h>  
    6. #include<event2/bufferevent.h>  
    7.   
    8.   
    9.   
    10. void accept_cb(int fd, short events, void* arg);  
    11. void socket_read_cb(bufferevent* bev, void* arg);  
    12. void event_cb(struct bufferevent *bev, short event, void *arg);  
    13. int tcp_server_init(int port, int listen_num);  
    14.   
    15. int main(int argc, char** argv)  
    16. {  
    17.   
    18.     int listener = tcp_server_init(9999, 10);  
    19.     if( listener == -1 )  
    20.     {  
    21.         perror(" tcp_server_init error ");  
    22.         return -1;  
    23.     }  
    24.   
    25.     struct event_base* base = event_base_new();  
    26.   
    27.     //添加监听客户端请求连接事件  
    28.     struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST,  
    29.                                         accept_cb, base);  
    30.     event_add(ev_listen, NULL);  
    31.   
    32.   
    33.     event_base_dispatch(base);  
    34.     event_base_free(base);  
    35.   
    36.   
    37.     return 0;  
    38. }  
    39.   
    40.   
    41.   
    42. void accept_cb(int fd, short events, void* arg)  
    43. {  
    44.     evutil_socket_t sockfd;  
    45.   
    46.     struct sockaddr_in client;  
    47.     socklen_t len = sizeof(client);  
    48.   
    49.     sockfd = ::accept(fd, (struct sockaddr*)&client, &len );  
    50.     evutil_make_socket_nonblocking(sockfd);  
    51.   
    52.     printf("accept a client %d ", sockfd);  
    53.   
    54.     struct event_base* base = (event_base*)arg;  
    55.   
    56.     bufferevent* bev = bufferevent_socket_new(base, sockfd, BEV_OPT_CLOSE_ON_FREE);  
    57.     bufferevent_setcb(bev, socket_read_cb, NULL, event_cb, arg);  
    58.   
    59.     bufferevent_enable(bev, EV_READ | EV_PERSIST);  
    60. }  
    61.   
    62.   
    63.   
    64. void socket_read_cb(bufferevent* bev, void* arg)  
    65. {  
    66.     char msg[4096];  
    67.   
    68.     size_t len = bufferevent_read(bev, msg, sizeof(msg));  
    69.   
    70.     msg[len] = '';  
    71.     printf("recv the client msg: %s", msg);  
    72.   
    73.   
    74.     char reply_msg[4096] = "I have recvieced the msg: ";  
    75.   
    76.     strcat(reply_msg + strlen(reply_msg), msg);  
    77.     bufferevent_write(bev, reply_msg, strlen(reply_msg));  
    78. }  
    79.   
    80.   
    81.   
    82. void event_cb(struct bufferevent *bev, short event, void *arg)  
    83. {  
    84.   
    85.     if (event & BEV_EVENT_EOF)  
    86.         printf("connection closed ");  
    87.     else if (event & BEV_EVENT_ERROR)  
    88.         printf("some other error ");  
    89.   
    90.     //这将自动close套接字和free读写缓冲区  
    91.     bufferevent_free(bev);  
    92. }  
    93.   
    94.   
    95. typedef struct sockaddr SA;  
    96. int tcp_server_init(int port, int listen_num)  
    97. {  
    98.     int errno_save;  
    99.     evutil_socket_t listener;  
    100.   
    101.     listener = ::socket(AF_INET, SOCK_STREAM, 0);  
    102.     if( listener == -1 )  
    103.         return -1;  
    104.   
    105.     //允许多次绑定同一个地址。要用在socket和bind之间  
    106.     evutil_make_listen_socket_reuseable(listener);  
    107.   
    108.     struct sockaddr_in sin;  
    109.     sin.sin_family = AF_INET;  
    110.     sin.sin_addr.s_addr = 0;  
    111.     sin.sin_port = htons(port);  
    112.   
    113.     if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )  
    114.         goto error;  
    115.   
    116.     if( ::listen(listener, listen_num) < 0)  
    117.         goto error;  
    118.   
    119.   
    120.     //跨平台统一接口,将套接字设置为非阻塞状态  
    121.     evutil_make_socket_nonblocking(listener);  
    122.   
    123.     return listener;  
    124.   
    125.     error:  
    126.         errno_save = errno;  
    127.         evutil_closesocket(listener);  
    128.         errno = errno_save;  
    129.   
    130.         return -1;  
    131. }  



    高等:

    客户端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include<sys/types.h>  
    2. #include<sys/socket.h>  
    3. #include<netinet/in.h>  
    4. #include<arpa/inet.h>  
    5. #include<errno.h>  
    6. #include<unistd.h>  
    7.   
    8. #include<stdio.h>  
    9. #include<string.h>  
    10. #include<stdlib.h>  
    11.   
    12. #include<event.h>  
    13. #include<event2/bufferevent.h>  
    14. #include<event2/buffer.h>  
    15. #include<event2/util.h>  
    16.   
    17.   
    18.   
    19.   
    20. int tcp_connect_server(const char* server_ip, int port);  
    21.   
    22.   
    23. void cmd_msg_cb(int fd, short events, void* arg);  
    24. void server_msg_cb(struct bufferevent* bev, void* arg);  
    25. void event_cb(struct bufferevent *bev, short event, void *arg);  
    26.   
    27. int main(int argc, char** argv)  
    28. {  
    29.     if( argc < 3 )  
    30.     {  
    31.         //两个参数依次是服务器端的IP地址、端口号  
    32.         printf("please input 2 parameter ");  
    33.         return -1;  
    34.     }  
    35.   
    36.     struct event_base *base = event_base_new();  
    37.   
    38.     struct bufferevent* bev = bufferevent_socket_new(base, -1,  
    39.                                                      BEV_OPT_CLOSE_ON_FREE);  
    40.   
    41.     //监听终端输入事件  
    42.     struct event* ev_cmd = event_new(base, STDIN_FILENO,  
    43.                                      EV_READ | EV_PERSIST,  
    44.                                      cmd_msg_cb, (void*)bev);  
    45.   
    46.   
    47.     event_add(ev_cmd, NULL);  
    48.   
    49.     struct sockaddr_in server_addr;  
    50.   
    51.     memset(&server_addr, 0, sizeof(server_addr) );  
    52.   
    53.     server_addr.sin_family = AF_INET;  
    54.     server_addr.sin_port = htons(atoi(argv[2]));  
    55.     inet_aton(argv[1], &server_addr.sin_addr);  
    56.   
    57.     bufferevent_socket_connect(bev, (struct sockaddr *)&server_addr,  
    58.                                sizeof(server_addr));  
    59.   
    60.   
    61.     bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void*)ev_cmd);  
    62.     bufferevent_enable(bev, EV_READ | EV_PERSIST);  
    63.   
    64.   
    65.   
    66.     event_base_dispatch(base);  
    67.   
    68.     printf("finished  ");  
    69.     return 0;  
    70. }  
    71.   
    72.   
    73.   
    74.   
    75.   
    76. void cmd_msg_cb(int fd, short events, void* arg)  
    77. {  
    78.     char msg[1024];  
    79.   
    80.     int ret = read(fd, msg, sizeof(msg));  
    81.     if( ret < 0 )  
    82.     {  
    83.         perror("read fail ");  
    84.         exit(1);  
    85.     }  
    86.   
    87.     struct bufferevent* bev = (struct bufferevent*)arg;  
    88.   
    89.     //把终端的消息发送给服务器端  
    90.     bufferevent_write(bev, msg, ret);  
    91. }  
    92.   
    93.   
    94. void server_msg_cb(struct bufferevent* bev, void* arg)  
    95. {  
    96.     char msg[1024];  
    97.   
    98.     size_t len = bufferevent_read(bev, msg, sizeof(msg));  
    99.     msg[len] = '';  
    100.   
    101.     printf("recv %s from server ", msg);  
    102. }  
    103.   
    104.   
    105. void event_cb(struct bufferevent *bev, short event, void *arg)  
    106. {  
    107.   
    108.     if (event & BEV_EVENT_EOF)  
    109.         printf("connection closed ");  
    110.     else if (event & BEV_EVENT_ERROR)  
    111.         printf("some other error ");  
    112.     else if( event & BEV_EVENT_CONNECTED)  
    113.     {  
    114.         printf("the client has connected to server ");  
    115.         return ;  
    116.     }  
    117.   
    118.     //这将自动close套接字和free读写缓冲区  
    119.     bufferevent_free(bev);  
    120.   
    121.     struct event *ev = (struct event*)arg;  
    122.     event_free(ev);  
    123. }  



    服务器端代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
      1. #include<netinet/in.h>    
      2. #include<sys/socket.h>    
      3. #include<unistd.h>    
      4.     
      5. #include<stdio.h>    
      6. #include<string.h>    
      7.     
      8. #include<event.h>    
      9. #include<listener.h>    
      10. #include<bufferevent.h>    
      11. #include<thread.h>    
      12.     
      13.     
      14. void listener_cb(evconnlistener *listener, evutil_socket_t fd,    
      15.                  struct sockaddr *sock, int socklen, void *arg);    
      16.     
      17. void socket_read_cb(bufferevent *bev, void *arg);    
      18. void socket_event_cb(bufferevent *bev, short events, void *arg);    
      19.     
      20. int main()    
      21. {    
      22.     //evthread_use_pthreads();//enable threads    
      23.     
      24.     struct sockaddr_in sin;    
      25.     memset(&sin, 0, sizeof(struct sockaddr_in));    
      26.     sin.sin_family = AF_INET;    
      27.     sin.sin_port = htons(9999);    
      28.     
      29.     event_base *base = event_base_new();    
      30.     evconnlistener *listener    
      31.             = evconnlistener_new_bind(base, listener_cb, base,    
      32.                                       LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,    
      33.                                       10, (struct sockaddr*)&sin,    
      34.                                       sizeof(struct sockaddr_in));    
      35.     
      36.     event_base_dispatch(base);    
      37.     
      38.     evconnlistener_free(listener);    
      39.     event_base_free(base);    
      40.     
      41.     return 0;    
      42. }    
      43.     
      44.     
      45. //一个新客户端连接上服务器了    
      46. //当此函数被调用时,libevent已经帮我们accept了这个客户端。该客户端的  
      47. //文件描述符为fd  
      48. void listener_cb(evconnlistener *listener, evutil_socket_t fd,    
      49.                  struct sockaddr *sock, int socklen, void *arg)    
      50. {    
      51.     printf("accept a client %d ", fd);    
      52.     
      53.     event_base *base = (event_base*)arg;    
      54.     
      55.     //为这个客户端分配一个bufferevent    
      56.     bufferevent *bev =  bufferevent_socket_new(base, fd,    
      57.                                                BEV_OPT_CLOSE_ON_FREE);    
      58.     
      59.     bufferevent_setcb(bev, socket_read_cb, NULL, socket_event_cb, NULL);    
      60.     bufferevent_enable(bev, EV_READ | EV_PERSIST);    
      61. }    
      62.     
      63.     
      64. void socket_read_cb(bufferevent *bev, void *arg)    
      65. {    
      66.     char msg[4096];    
      67.     
      68.     size_t len = bufferevent_read(bev, msg, sizeof(msg)-1 );    
      69.     
      70.     msg[len] = '';    
      71.     printf("server read the data %s ", msg);    
      72.     
      73.     char reply[] = "I has read your data";    
      74.     bufferevent_write(bev, reply, strlen(reply) );    
      75. }    
      76.     
      77.     
      78. void socket_event_cb(bufferevent *bev, short events, void *arg)    
      79. {    
      80.     if (events & BEV_EVENT_EOF)    
      81.         printf("connection closed ");    
      82.     else if (events & BEV_EVENT_ERROR)    
      83.         printf("some other error ");    
      84.     
      85.     //这将自动close套接字和free读写缓冲区    
      86.     bufferevent_free(bev);    
      87. }    
  • 相关阅读:
    virtual Box在Centos 7上的安装
    Spark MLlib使用有感
    storm集群配置
    eclipse配置hadoop插件
    HDFS的java接口——简化HDFS文件系统操作
    【hbase】——HBase 写优化之 BulkLoad 实现数据快速入库
    【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
    【转】RHadoop实践系列之二:RHadoop安装与使用
    【转】RHadoop实践系列之一:Hadoop环境搭建
    Hadoop生态系统如何选择搭建
  • 原文地址:https://www.cnblogs.com/jjj250/p/6351326.html
Copyright © 2011-2022 走看看