Libevent使用例子,从简单到复杂

2023-11-08

出处: http://blog.csdn.net/luotuo44/article/details/39670221



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

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

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

        


初等:

客户端代码:

  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\n");  
  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\n");  
  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 \n");  
  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] = '\0';  
  101.   
  102.     printf("recv %s from server\n", 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. }  
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<event.h>
#include<event2/util.h>




int tcp_connect_server(const char* server_ip, int port);


void cmd_msg_cb(int fd, short events, void* arg);
void socket_read_cb(int fd, short events, void *arg);

int main(int argc, char** argv)
{
    if( argc < 3 )
    {
        printf("please input 2 parameter\n");
        return -1;
    }


    //两个参数依次是服务器端的IP地址、端口号
    int sockfd = tcp_connect_server(argv[1], atoi(argv[2]));
    if( sockfd == -1)
    {
        perror("tcp_connect error ");
        return -1;
    }

    printf("connect to server successful\n");

    struct event_base* base = event_base_new();

    struct event *ev_sockfd = event_new(base, sockfd,
                                        EV_READ | EV_PERSIST,
                                        socket_read_cb, NULL);
    event_add(ev_sockfd, NULL);

    //监听终端输入事件
    struct event* ev_cmd = event_new(base, STDIN_FILENO,
                                      EV_READ | EV_PERSIST, cmd_msg_cb,
                                      (void*)&sockfd);


    event_add(ev_cmd, NULL);

    event_base_dispatch(base);

    printf("finished \n");
    return 0;
}






void cmd_msg_cb(int fd, short events, void* arg)
{
    char msg[1024];

    int ret = read(fd, msg, sizeof(msg));
    if( ret <= 0 )
    {
        perror("read fail ");
        exit(1);
    }

    int sockfd = *((int*)arg);

    //把终端的消息发送给服务器端
    //为了简单起见,不考虑写一半数据的情况
    write(sockfd, msg, ret);
}


void socket_read_cb(int fd, short events, void *arg)
{
    char msg[1024];

    //为了简单起见,不考虑读一半数据的情况
    int len = read(fd, msg, sizeof(msg)-1);
    if( len <= 0 )
    {
        perror("read fail ");
        exit(1);
    }

    msg[len] = '\0';

    printf("recv %s from server\n", msg);
}



typedef struct sockaddr SA;
int tcp_connect_server(const char* server_ip, int port)
{
    int sockfd, status, save_errno;
    struct sockaddr_in server_addr;

    memset(&server_addr, 0, sizeof(server_addr) );

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    status = inet_aton(server_ip, &server_addr.sin_addr);

    if( status == 0 ) //the server_ip is not valid value
    {
        errno = EINVAL;
        return -1;
    }

    sockfd = ::socket(PF_INET, SOCK_STREAM, 0);
    if( sockfd == -1 )
        return sockfd;


    status = ::connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );

    if( status == -1 )
    {
        save_errno = errno;
        ::close(sockfd);
        errno = save_errno; //the close may be error
        return -1;
    }

    evutil_make_socket_nonblocking(sockfd);

    return sockfd;
}


服务器端代码:

  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\n", 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\n");  
  75.         event_free(ev);  
  76.         close(fd);  
  77.         return ;  
  78.     }  
  79.   
  80.     msg[len] = '\0';  
  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. }  
#include<stdio.h>
#include<string.h>
#include<errno.h>

#include<unistd.h>
#include<event.h>



void accept_cb(int fd, short events, void* arg);
void socket_read_cb(int fd, short events, void *arg);

int tcp_server_init(int port, int listen_num);

int main(int argc, char** argv)
{

    int listener = tcp_server_init(9999, 10);
    if( listener == -1 )
    {
        perror(" tcp_server_init error ");
        return -1;
    }

    struct event_base* base = event_base_new();

    //添加监听客户端请求连接事件
    struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST,
                                        accept_cb, base);
    event_add(ev_listen, NULL);


    event_base_dispatch(base);

    return 0;
}



void accept_cb(int fd, short events, void* arg)
{
    evutil_socket_t sockfd;

    struct sockaddr_in client;
    socklen_t len = sizeof(client);

    sockfd = ::accept(fd, (struct sockaddr*)&client, &len );
    evutil_make_socket_nonblocking(sockfd);

    printf("accept a client %d\n", sockfd);

    struct event_base* base = (event_base*)arg;

    //仅仅是为了动态创建一个event结构体
    struct event *ev = event_new(NULL, -1, 0, NULL, NULL);
    //将动态创建的结构体作为event的回调参数
    event_assign(ev, base, sockfd, EV_READ | EV_PERSIST,
                 socket_read_cb, (void*)ev);

    event_add(ev, NULL);
}


void socket_read_cb(int fd, short events, void *arg)
{
    char msg[4096];
    struct event *ev = (struct event*)arg;
    int len = read(fd, msg, sizeof(msg) - 1);



    if( len <= 0 )
    {
        printf("some error happen when read\n");
        event_free(ev);
        close(fd);
        return ;
    }

    msg[len] = '\0';
    printf("recv the client msg: %s", msg);

    char reply_msg[4096] = "I have recvieced the msg: ";
    strcat(reply_msg + strlen(reply_msg), msg);

    write(fd, reply_msg, strlen(reply_msg) );
}



typedef struct sockaddr SA;
int tcp_server_init(int port, int listen_num)
{
    int errno_save;
    evutil_socket_t listener;

    listener = ::socket(AF_INET, SOCK_STREAM, 0);
    if( listener == -1 )
        return -1;

    //允许多次绑定同一个地址。要用在socket和bind之间
    evutil_make_listen_socket_reuseable(listener);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(port);

    if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
        goto error;

    if( ::listen(listener, listen_num) < 0)
        goto error;


    //跨平台统一接口,将套接字设置为非阻塞状态
    evutil_make_socket_nonblocking(listener);

    return listener;

    error:
        errno_save = errno;
        evutil_closesocket(listener);
        errno = errno_save;

        return -1;
}



中等:

客户端代码:

  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\n");  
  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\n");  
  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 \n");  
  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] = '\0';  
  97.   
  98.     printf("recv %s from server\n", 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\n");  
  107.     else if (event & BEV_EVENT_ERROR)  
  108.         printf("some other error\n");  
  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. }  
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<event.h>
#include<event2/bufferevent.h>
#include<event2/buffer.h>
#include<event2/util.h>




int tcp_connect_server(const char* server_ip, int port);


void cmd_msg_cb(int fd, short events, void* arg);
void server_msg_cb(struct bufferevent* bev, void* arg);
void event_cb(struct bufferevent *bev, short event, void *arg);

int main(int argc, char** argv)
{
    if( argc < 3 )
    {
        printf("please input 2 parameter\n");
        return -1;
    }


    //两个参数依次是服务器端的IP地址、端口号
    int sockfd = tcp_connect_server(argv[1], atoi(argv[2]));
    if( sockfd == -1)
    {
        perror("tcp_connect error ");
        return -1;
    }

    printf("connect to server successful\n");

    struct event_base* base = event_base_new();

    struct bufferevent* bev = bufferevent_socket_new(base, sockfd,
                                                     BEV_OPT_CLOSE_ON_FREE);

    //监听终端输入事件
    struct event* ev_cmd = event_new(base, STDIN_FILENO,
                                      EV_READ | EV_PERSIST, cmd_msg_cb,
                                      (void*)bev);
    event_add(ev_cmd, NULL);

    //当socket关闭时会用到回调参数
    bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void*)ev_cmd);
    bufferevent_enable(bev, EV_READ | EV_PERSIST);


    event_base_dispatch(base);

    printf("finished \n");
    return 0;
}






void cmd_msg_cb(int fd, short events, void* arg)
{
    char msg[1024];

    int ret = read(fd, msg, sizeof(msg));
    if( ret < 0 )
    {
        perror("read fail ");
        exit(1);
    }

    struct bufferevent* bev = (struct bufferevent*)arg;

    //把终端的消息发送给服务器端
    bufferevent_write(bev, msg, ret);
}


void server_msg_cb(struct bufferevent* bev, void* arg)
{
    char msg[1024];

    size_t len = bufferevent_read(bev, msg, sizeof(msg));
    msg[len] = '\0';

    printf("recv %s from server\n", msg);
}


void event_cb(struct bufferevent *bev, short event, void *arg)
{

    if (event & BEV_EVENT_EOF)
        printf("connection closed\n");
    else if (event & BEV_EVENT_ERROR)
        printf("some other error\n");

    //这将自动close套接字和free读写缓冲区
    bufferevent_free(bev);

    struct event *ev = (struct event*)arg;
    //因为socket已经没有,所以这个event也没有存在的必要了
    event_free(ev);
}


typedef struct sockaddr SA;
int tcp_connect_server(const char* server_ip, int port)
{
    int sockfd, status, save_errno;
    struct sockaddr_in server_addr;

    memset(&server_addr, 0, sizeof(server_addr) );

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    status = inet_aton(server_ip, &server_addr.sin_addr);

    if( status == 0 ) //the server_ip is not valid value
    {
        errno = EINVAL;
        return -1;
    }

    sockfd = ::socket(PF_INET, SOCK_STREAM, 0);
    if( sockfd == -1 )
        return sockfd;


    status = ::connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );

    if( status == -1 )
    {
        save_errno = errno;
        ::close(sockfd);
        errno = save_errno; //the close may be error
        return -1;
    }

    evutil_make_socket_nonblocking(sockfd);

    return sockfd;
}



服务器端代码:

  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\n", 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] = '\0';  
  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\n");  
  87.     else if (event & BEV_EVENT_ERROR)  
  88.         printf("some other error\n");  
  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. }  
#include<stdio.h>
#include<string.h>
#include<errno.h>

#include<event.h>
#include<event2/bufferevent.h>



void accept_cb(int fd, short events, void* arg);
void socket_read_cb(bufferevent* bev, void* arg);
void event_cb(struct bufferevent *bev, short event, void *arg);
int tcp_server_init(int port, int listen_num);

int main(int argc, char** argv)
{

    int listener = tcp_server_init(9999, 10);
    if( listener == -1 )
    {
        perror(" tcp_server_init error ");
        return -1;
    }

    struct event_base* base = event_base_new();

    //添加监听客户端请求连接事件
    struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST,
                                        accept_cb, base);
    event_add(ev_listen, NULL);


    event_base_dispatch(base);
    event_base_free(base);


    return 0;
}



void accept_cb(int fd, short events, void* arg)
{
    evutil_socket_t sockfd;

    struct sockaddr_in client;
    socklen_t len = sizeof(client);

    sockfd = ::accept(fd, (struct sockaddr*)&client, &len );
    evutil_make_socket_nonblocking(sockfd);

    printf("accept a client %d\n", sockfd);

    struct event_base* base = (event_base*)arg;

    bufferevent* bev = bufferevent_socket_new(base, sockfd, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bev, socket_read_cb, NULL, event_cb, arg);

    bufferevent_enable(bev, EV_READ | EV_PERSIST);
}



void socket_read_cb(bufferevent* bev, void* arg)
{
    char msg[4096];

    size_t len = bufferevent_read(bev, msg, sizeof(msg));

    msg[len] = '\0';
    printf("recv the client msg: %s", msg);


    char reply_msg[4096] = "I have recvieced the msg: ";

    strcat(reply_msg + strlen(reply_msg), msg);
    bufferevent_write(bev, reply_msg, strlen(reply_msg));
}



void event_cb(struct bufferevent *bev, short event, void *arg)
{

    if (event & BEV_EVENT_EOF)
        printf("connection closed\n");
    else if (event & BEV_EVENT_ERROR)
        printf("some other error\n");

    //这将自动close套接字和free读写缓冲区
    bufferevent_free(bev);
}


typedef struct sockaddr SA;
int tcp_server_init(int port, int listen_num)
{
    int errno_save;
    evutil_socket_t listener;

    listener = ::socket(AF_INET, SOCK_STREAM, 0);
    if( listener == -1 )
        return -1;

    //允许多次绑定同一个地址。要用在socket和bind之间
    evutil_make_listen_socket_reuseable(listener);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(port);

    if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
        goto error;

    if( ::listen(listener, listen_num) < 0)
        goto error;


    //跨平台统一接口,将套接字设置为非阻塞状态
    evutil_make_socket_nonblocking(listener);

    return listener;

    error:
        errno_save = errno;
        evutil_closesocket(listener);
        errno = errno_save;

        return -1;
}



高等:

客户端代码:

  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\n");  
  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 \n");  
  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] = '\0';  
  100.   
  101.     printf("recv %s from server\n", 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\n");  
  110.     else if (event & BEV_EVENT_ERROR)  
  111.         printf("some other error\n");  
  112.     else if( event & BEV_EVENT_CONNECTED)  
  113.     {  
  114.         printf("the client has connected to server\n");  
  115.         return ;  
  116.     }  
  117.   
  118.     //这将自动close套接字和free读写缓冲区  
  119.     bufferevent_free(bev);  
  120.   
  121.     struct event *ev = (struct event*)arg;  
  122.     event_free(ev);  
  123. }  
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<event.h>
#include<event2/bufferevent.h>
#include<event2/buffer.h>
#include<event2/util.h>




int tcp_connect_server(const char* server_ip, int port);


void cmd_msg_cb(int fd, short events, void* arg);
void server_msg_cb(struct bufferevent* bev, void* arg);
void event_cb(struct bufferevent *bev, short event, void *arg);

int main(int argc, char** argv)
{
    if( argc < 3 )
    {
        //两个参数依次是服务器端的IP地址、端口号
        printf("please input 2 parameter\n");
        return -1;
    }

    struct event_base *base = event_base_new();

    struct bufferevent* bev = bufferevent_socket_new(base, -1,
                                                     BEV_OPT_CLOSE_ON_FREE);

    //监听终端输入事件
    struct event* ev_cmd = event_new(base, STDIN_FILENO,
                                     EV_READ | EV_PERSIST,
                                     cmd_msg_cb, (void*)bev);


    event_add(ev_cmd, NULL);

    struct sockaddr_in server_addr;

    memset(&server_addr, 0, sizeof(server_addr) );

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi(argv[2]));
    inet_aton(argv[1], &server_addr.sin_addr);

    bufferevent_socket_connect(bev, (struct sockaddr *)&server_addr,
                               sizeof(server_addr));


    bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void*)ev_cmd);
    bufferevent_enable(bev, EV_READ | EV_PERSIST);



    event_base_dispatch(base);

    printf("finished \n");
    return 0;
}





void cmd_msg_cb(int fd, short events, void* arg)
{
    char msg[1024];

    int ret = read(fd, msg, sizeof(msg));
    if( ret < 0 )
    {
        perror("read fail ");
        exit(1);
    }

    struct bufferevent* bev = (struct bufferevent*)arg;

    //把终端的消息发送给服务器端
    bufferevent_write(bev, msg, ret);
}


void server_msg_cb(struct bufferevent* bev, void* arg)
{
    char msg[1024];

    size_t len = bufferevent_read(bev, msg, sizeof(msg));
    msg[len] = '\0';

    printf("recv %s from server\n", msg);
}


void event_cb(struct bufferevent *bev, short event, void *arg)
{

    if (event & BEV_EVENT_EOF)
        printf("connection closed\n");
    else if (event & BEV_EVENT_ERROR)
        printf("some other error\n");
    else if( event & BEV_EVENT_CONNECTED)
    {
        printf("the client has connected to server\n");
        return ;
    }

    //这将自动close套接字和free读写缓冲区
    bufferevent_free(bev);

    struct event *ev = (struct event*)arg;
    event_free(ev);
}




服务器端代码:

  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\n", 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] = '\0';    
  71.     printf("server read the data %s\n", 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\n");    
  82.     else if (events & BEV_EVENT_ERROR)    
  83.         printf("some other error\n");    
  84.     
  85.     //这将自动close套接字和free读写缓冲区    
  86.     bufferevent_free(bev);    
  87. }    
#include<netinet/in.h>  
#include<sys/socket.h>  
#include<unistd.h>  
  
#include<stdio.h>  
#include<string.h>  
  
#include<event.h>  
#include<listener.h>  
#include<bufferevent.h>  
#include<thread.h>  
  
  
void listener_cb(evconnlistener *listener, evutil_socket_t fd,  
                 struct sockaddr *sock, int socklen, void *arg);  
  
void socket_read_cb(bufferevent *bev, void *arg);  
void socket_event_cb(bufferevent *bev, short events, void *arg);  
  
int main()  
{  
    //evthread_use_pthreads();//enable threads  
  
    struct sockaddr_in sin;  
    memset(&sin, 0, sizeof(struct sockaddr_in));  
    sin.sin_family = AF_INET;  
    sin.sin_port = htons(9999);  
  
    event_base *base = event_base_new();  
    evconnlistener *listener  
            = evconnlistener_new_bind(base, listener_cb, base,  
                                      LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,  
                                      10, (struct sockaddr*)&sin,  
                                      sizeof(struct sockaddr_in));  
  
    event_base_dispatch(base);  
  
    evconnlistener_free(listener);  
    event_base_free(base);  
  
    return 0;  
}  
  
  
//一个新客户端连接上服务器了  
//当此函数被调用时,libevent已经帮我们accept了这个客户端。该客户端的
//文件描述符为fd
void listener_cb(evconnlistener *listener, evutil_socket_t fd,  
                 struct sockaddr *sock, int socklen, void *arg)  
{  
    printf("accept a client %d\n", fd);  
  
    event_base *base = (event_base*)arg;  
  
    //为这个客户端分配一个bufferevent  
    bufferevent *bev =  bufferevent_socket_new(base, fd,  
                                               BEV_OPT_CLOSE_ON_FREE);  
  
    bufferevent_setcb(bev, socket_read_cb, NULL, socket_event_cb, NULL);  
    bufferevent_enable(bev, EV_READ | EV_PERSIST);  
}  
  
  
void socket_read_cb(bufferevent *bev, void *arg)  
{  
    char msg[4096];  
  
    size_t len = bufferevent_read(bev, msg, sizeof(msg)-1 );  
  
    msg[len] = '\0';  
    printf("server read the data %s\n", msg);  
  
    char reply[] = "I has read your data";  
    bufferevent_write(bev, reply, strlen(reply) );  
}  
  
  
void socket_event_cb(bufferevent *bev, short events, void *arg)  
{  
    if (events & BEV_EVENT_EOF)  
        printf("connection closed\n");  
    else if (events & BEV_EVENT_ERROR)  
        printf("some other error\n");  
  
    //这将自动close套接字和free读写缓冲区  
    bufferevent_free(bev);  
}  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Libevent使用例子,从简单到复杂 的相关文章

  • libevent实现的HTTP Server

    在使用C语言编码时 有时候需要实现一个HTTP接口 我们可以选择使用libevent库来实现 以下代码演示了使用libevent 并同时支持多线程处理HTTP的请求 头文件 引入的头文件 span class token macro pro
  • libevent详解四(http服务)

    创建基于libevent的http服务 先上代码 span class token macro property span class token directive keyword include span span class toke
  • LibEvent-Demo

    libevent test cpp 定义控制台应用程序的入口点 include 34 stdafx h 34 pragma comment lib 34 ws2 32 lib 34 pragma comment lib 34 wsock32
  • http服务器使用libevent实现get和post请求实例

    最近在工作中使用到了libenevt封装的http xff0c 在做curl模拟get post请求时遇到了一些问题 xff0c 今天就记录下正确的http服务端处理方法 xff0c 欢迎观摩 一 libevent介绍 首先 xff0c 咱
  • libevent之eventop

    功能 xff1a IO处理模型 架构 xff1a 实现 xff1a event internal h定义eventop结构体 xff0c 在 c文件实例化生成对应的全局对象 xff0c 如在poll c中生成pollops对象 event
  • libevent的http服务详解

    libevent的http服务详解 即远程调用 xff0c 得到一个call ID然后验证外部远程参数 span class token function evrpc request cb span span class token pun
  • minix3下安装libevent

    libevent是一个c语言编写的事件框架 xff0c 支持异步IO 定时器 信号事件 它支持跨平台 xff0c 大部分都是在linux下安装并使用 xff0c 今天介绍在unix系统minix3上的安装 minix3上编译环境是clang
  • Libevent源码深度剖析-张亮(转载)

    https blog csdn net xp178171640 article details 105490027
  • 处理大并发之三 对libevent的初步认识 (必看)

    https blog csdn net feitianxuxue article details 9360347 处理大并发之三 对libevent的初步认识 首先翻译下http www wangafu net nickm libevent
  • libevent 源码分析丨libevent组件构成以及编程要领

    1 前言 Libevent是一个轻量级的开源高性能网络库 使用者众多 研究者更甚 相关文章也不少 写这一系列文章的用意在于 一则分享心得 二则对libevent代码和设计思想做系统的 更深层次的分析 写出来 也可供后来者参考 文章较长 建议
  • libevent堵包,大包收取速度慢问题

    libevent堵包 大包收取速度慢问题 最近在使用libevent的时候 发现包收取速度慢 单次只能读取到16384个字节 如是在libevent源码里搜索了下16384 发现libevent对单词读取包有限制 可通过下面两个接口修改读写
  • Linux下使用gtest对接口进行单元测试

    目录 1 背景 2 gtest 断言 2 1 布尔值判断 2 2 二进制比较 2 3 字符串比较 2 4 浮点数比较 3 实践 3 1 框架使用 3 2 用例编写 3 3 编译运行 4 结论 1 背景 工程中涉及基础接口的设计 为了保证接口
  • libevent服务端,单线程应用

    libevent版本 libevent 2 1 12 stable include
  • Linux高性能I/O框架库Libevent介绍

    C C Linux服务器开发 后台架构师知识体系 这篇文章主要讲一下Libevent库的内容 顺便对I O库整体做个介绍 Linux服务器程序必须处理的三类事件 I O事件 信号 定时事件 在处理这三类事件时我们通常需要考虑如下三个问题 统
  • libevent(6)windows上使用iocp网络模型

    windows操作系统上不能使用epoll模型 只能使用iocp网络模型 这里我把怎么在windows上使用iocp的代码直接贴上 include
  • libevent服务端,多线程应用

    下面的方式是创建多个event base来处理多线程的 主event base用来处理连接请求 各个子event base用来处理读写和关闭请求 另一种方式是 所有的连接 读写 断开操作 都在一个event base里面 然后当读到数据时
  • libevent涉及的知识积累

    O 1 实现单链表插入删除 阅读libevent源码时发现了linux提供的一个链表 宏定义如下 define LIST ENTRY type struct struct type le next next element struct t
  • 【Linux】Libevent库

    Libevent 高性能I O框架库 底层封装了select poll epoll 便于使用 I O框架库以库函数的形式 封装了较为底层的系统调用 给应用程序提供了一组更便于使用的接口 特点 1 跨平台 2 统一事件源 I O事件 信号 定
  • ubuntu中libevent开发库的安装

    我正在使用 ubuntu 10 10 尝试安装 libevent 开发库 libevent1 和 libevent2 我使用了以下命令 apt get install libevent dev libevent1 dev But it sh
  • Android 交叉编译 libevent

    我一直在尝试将 libevent 交叉编译到 Android 我想知道我做错了什么并获得一些帮助 我尝试构建的版本是 libevent 2 0 19 stable 我开始按照以下描述的步骤进行操作http warpedtimes wordp

随机推荐

  • 那些开发过程中需要遵守的开发规范

    入职公司三天 没干啥其他活 基本在配置本地环境和阅读相关文档 技术方面公司基本用的是主流的技术体系 入职后需要先阅读阿里的开发规范和其他的一些产研文档 今天整理一些平时需要关注的阿里规约和数据库开发规范 方便今后在开发过程中查阅 文章目录
  • js game (.^-^.)

    try 新手 可能会有点小问题 欢迎指出 var lc 10 var cl 12 var e 0 v new Array for var i 0 i lt 25 i var a Math random cl 1 lc lc点 a a 100
  • 创建Umi项目

    关于Umi的网站 点开百度搜索umi 注意 浏览器直接搜索和百度搜索打开的官网是有区别的 百度会优先打开国内的网站 准备工作 首先得有node 版本要在14以上 后面是用yarn安装 所以没有yarn包管理器 安装下载一个 1 全局安装ya
  • hbuilder开发uniapp配置安卓模拟器

    安卓模拟器使用的是蓝蝶模拟器 配置如下 然后打开蓝蝶模拟器软件 点击设置 点击引擎设置 勾选允许AADB连接 各个模拟器端口配置 模拟器名称 连接默认端口 夜神安卓模拟器夜神安卓模拟器 62001 逍遥安卓模拟器逍遥安卓模拟器 21503
  • 拦截器HandlerInterceptorAdapter使用方法

    一 Interceptor定义 拦截器是在面向切面编程中应用的 就是在你的service或者一个方法前调用一个方法 或者在方法后调用一个方法 是基于JAVA的反射机制 1 拦截器 Interceptor 执行顺序 1 请求到达 Dispat
  • 用div来代替table

    用div来代替table 概述 实战 概述 table是我们日常开发中经常用到的HTML标签 但我们也经常因为table饱受折磨 原生的table的样式丑出天际 第三方框架的样式可能样式是好看点了 但可能并不是我们想要的样子 面对这些情况
  • [Matlab科学绘图] 由欧拉角绘制极图和反极图

    因为科研需要 需要自己仿真产生一些晶粒方向 并对其进行极图和反极图展示 在小木虫上找到一个matlab工具包mtex 利用此工具包可以绘制极图和反极图 但是并没有现成的程序可供参考 于是自己摸索出可以利用欧拉角绘制极图和反极图 记录于此供大
  • 【手把手教你】使用DoWhy做因果推断分析

    引言 因果推断是一种统计和哲学框架 旨在从数据中识别变量之间的因果关系 而不仅仅是相关性或关联 换句话说 它试图解答 如果我做X 会发生什么 这类问题 而非仅仅描述 X与Y有关联 这种观察性的信息 在金融量化中 因果推断的应用相当重要 金融
  • GEE学习记录(四)基于NPP和GPP数据集产生NPP8天、月度数据

    GEE官网提供的GPP数据集有8天的 但是NPP都是以年为单位的 挺不友好的 此链接是对数据集的介绍 链接 想要产生NPP8天 月度的数据集 需要利用NPP年度数据和GPP八天数据进行计算 代码如下 参考链接 首先导入八天的GPP数据和年度
  • TensorFlow 2.0 —— 模型训练

    目录 1 Keras版本模型训练 1 1 构造模型 顺序模型 函数式模型 子类模型 1 2 模型训练 model fit 1 3 模型验证 model evaluate 1 4 模型预测 model predict 1 5 使用样本加权和类
  • JSP四大域

    JSP四大域对象 pageContext 当前jsp页面范围内有效 request 一次请求内有效 session 一次会话范围内有效 也就是打开浏览器访问服务器到关闭浏览器 application 整个Web工程内有效 作用范围 创建一个
  • Arthas线上监控诊断产品[学习笔记]

    1下载启动arthas tunnel server Arthas Tunnel arthasarthas 使用文档https arthas aliyun com doc tunnel html E4 B8 8B E8 BD BD E9 83
  • Ceph集群生产环境安装部署

    前言 ceph的组件以及工作流程非常的复杂 是一个庞大的系统 在尝试ceph之前尽量多查阅官方的文档 理解ceph的mon osd mds pg pool等各组件 Unit的协同工作方式 Ceph官方文档 一 配置规划 二 部署 1 ntp
  • 超强OCR文字识别软件 图像文字识别软件工具-独有直接屏幕截图识别功能

    原文地址 http blog sina com cn s blog 4d36b4ba0100vnzc html 相关文章 1 Screen OCR 屏幕画面截屏工具 13 5 官方绿色版 http www newasp net soft 6
  • 人的一生(none)

    曾仕强 情绪管理 要有理想 情绪负债 享受错误的决定 错误嘴巴推给别人心里推给自己 没有人会因为你的抱怨而改变 只有改变自己 立场不同 讲话不一样 反求诸己 治标方法 散步 发泄 要看开 不要看破 被看待事情的观点所困扰 而不是被事情所困扰
  • linux 系统命令行查看电池剩余电量

    proc acpi battery BAT0 state 文件里的remaining capacity表示剩余电量 proc acpi battery BAT0 info 文件里的last full capacity表示满电量 如果有多块电
  • python数据分析——pyecharts折线图全解(小白必看)

    折线图是排列在工作表的列或行中的数据可以绘制到折线图中 折线图可以显示随时间 根据常用比例设置 而变化的连续数据 因此非常适用于显示在相等时间间隔下数据的趋势 下面我给大家介绍一下如何用pyecharts画出各种折线图 1 基本折线图 im
  • 【WSL2】win11创建秒级启动openEuler虚拟机

    前言 Windows上安装openEuler虚拟机 现在大多采用的是 vmware workstation virtual box 方案 可以完整地体验openEuler系统以及使用图形界面 这个方案的缺点是启动慢 资源消耗大 性能损耗大
  • VMware虚拟机安装+Ubuntu安装+VMware Tools安装+Ubuntu下g++编译器的安装+虚拟机中系统的移动

    一 VMware虚拟机安装 Ubuntu安装 本人VMware15 Pro Ubuntu18 04 06 LTS 该部分安装可见博客 提示 VMware15 Pro可在win7及以上系统中安装 VMware Workstation 16 P
  • Libevent使用例子,从简单到复杂

    出处 http blog csdn net luotuo44 article details 39670221 本文从简单到复杂 展示如何使用libevent 网上的许多例子都是只有服务器端的 本文里面客户端和服务器端都有 以飨读者 关于l