Libevent use examples, from simple to complex

Source: Internet
Author: User
Tags set socket htons


Reprint Please specify source: http://blog.csdn.net/luotuo44/article/details/39670221



This article is from simple to complex. show how to use Libevent. Many examples on the Web are only server-side, this article in the client and server side have, readers.

Some questions about Libevent programming you can read the Libevent Programming troubleshooter. If the reader also wants to know the detailed implementation of Libevent, he can read the Libevent source code Analysis system article.

Don't say so much. directly on the code.


Elementary: Client code:

#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 a        RGC, char** argv) {if (ARGC < 3) {printf ("Please input 2 parameter\n");    return-1;    }//Two parameters in turn is the server-side IP address, port number 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); Monitoring terminal input event struct event* Ev_cmd = event_new (base, Stdin_fileno, Ev_read |    Ev_persist, CMD_MSG_CB, (void*) &AMP;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); Send the terminal message to the server//For simplicity. Case Write (SOCKFD, MSG, ret) without considering writing half of the data;}    void Socket_read_cb (int fd, short events, void *arg) {char msg[1024];    For the sake of simplicity, do not consider the case of reading half of the data int len = read (fd, MSG, sizeof (MSG)-1);        if (len <= 0) {perror ("read fail");    Exit (1);    } Msg[len] = ' + '; 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 error return-1;    } evutil_make_socket_nonblocking (SOCKFD); return SOCKFD;}


Server-side code:

#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_se    Rver_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 (); Join listener Client Request Connection Event 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;    However, in order to dynamically create an event struct struct event *ev = event_new (null,-1, 0, NULL, NULL); Dynamically created structures as callback parameters for 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] = ' + ';    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; Agree to bind the same address multiple times.

To be used between the socket and 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; Cross-platform unified interface. Set socket to non-clogging state evutil_make_socket_nonblocking (listener); return listener; Error:errno_save = errno; Evutil_closesocket (listener); errno = Errno_save; return-1;}




Medium: Client code:

#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;    }//Two parameters in turn is the server-side IP address, port number 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); Monitoring terminal input event struct event* Ev_cmd = event_new (base, Stdin_fileno, Ev_read |    Ev_persist, CMD_MSG_CB, (void*) Bev);    Event_add (Ev_cmd, NULL);    Callback parameters are used when the socket is closed 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; Send the terminal message to the server-side 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] = ' + '; printf ("recv %s from server\n ", msg);} void Event_cb (struct bufferevent *bev, short event, void *arg) {if (Event & bev_event_eof) printf ("Connectio    n closed\n ");    else if (event & Bev_event_error) printf ("Some other error\n");    This will self-actively close the socket and free read-write buffer bufferevent_free (BEV);    struct Event *ev = (struct event*) arg; Because the socket is not already there, there is no need for this event to exist 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 error return-1;    } evutil_make_socket_nonblocking (SOCKFD); return SOCKFD;}



Server-side code:

#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 (); Join listener Client Request Connection Event 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] = ' + ';    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 ("Connectio    n closed\n ");    else if (event & Bev_event_error) printf ("Some other error\n"); This will self-actively close the socket and free read-write buffer 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; Agree to bind the same address multiple times.

To be used between the socket and 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; Cross-platform unified interface, set socket to non-clogging state evutil_make_socket_nonblocking (listener); return listener; Error:errno_save = errno; Evutil_closesocket (listener); errno = Errno_save; return-1;}




Advanced: Client code:

#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) {//two parameters in turn is the server-side IP address, port number printf ("Please input 2 PA        Rameter\n ");    return-1;    } struct Event_base *base = event_base_new (); struct bufferevent* Bev = bufferevent_socket_new (base,-1, Bev_opt_clo    Se_on_free);                   Monitor terminal input event 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; Send the terminal message to the server-side 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] = ' + '; printf ("Recv%s from server\n", msg);} void Event_cb (struct bufferevent *bev, short event, void *arg) {if (Event & bev_event_eof) printf ("Connectio    n 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;    }//This will Self-actively close the socket and free read-write buffer bufferevent_free (BEV);    struct Event *ev = (struct event*) arg; Event_free (EV);}



Server-side code:

#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 & lt;thread.h> void Listener_cb (Evconnlistener *listener, evutil_socket_t fd, struct sockaddr *SOC    K, 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, ten, (struct sockaddr*) & sin, sizeof (struct sockaddr_in));        Event_base_dispatch (base);      Evconnlistener_free (listener);        Event_base_free (base);  return 0; }//A new client is connected to the server//When this function is called, Libevent has helped us accept the client. The client's//File Description descriptor is fdvoid 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;                                                 Assign this client a 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] = ' + '; printf ("Server read the data%s\n", MSG);      Char reply[] = "I have read your data";  Bufferevent_write (Bev, reply, strlen (reply)); } void Socket_event_cb (Bufferevent *bev, short events, void *arg) {if (Events & bev_event_eof) pr      intf ("Connection closed\n");        else if (events & Bev_event_error) printf ("Some other error\n");  This will self-actively close the socket and free read-write buffer bufferevent_free (BEV);   }






Libevent use examples, from simple to complex

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.