Advertisement
Guest User

Untitled

a guest
Nov 24th, 2010
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.98 KB | None | 0 0
  1. #include <event2/listener.h>
  2. #include <event2/bufferevent.h>
  3. #include <event2/buffer.h>
  4. #include <event2/thread.h>
  5.  
  6. #include <arpa/inet.h>
  7.  
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <errno.h>
  12. #include <unistd.h>
  13.  
  14. #include <pthread.h>
  15.  
  16. /* g++ Test_libevent.cpp -o Test_libevent -levent_core -levent_pthreads && ./Test_libevent  */
  17.  
  18. static void
  19. echo_read_cb(struct bufferevent *bev, void *ctx)
  20. {
  21.         struct evbuffer *input = bufferevent_get_input(bev);
  22.         struct evbuffer *output = bufferevent_get_output(bev);
  23.         evbuffer_add_buffer(output, input);
  24. }
  25.  
  26. static void
  27. echo_event_cb(struct bufferevent *bev, short events, void *ctx)
  28. {
  29.         fprintf( stderr, "An event from one of the clients...\n" );
  30.         if (events & BEV_EVENT_ERROR)
  31.                 perror("Error from bufferevent");
  32.         if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
  33.                 bufferevent_free(bev);
  34.         }
  35. }
  36.  
  37. static void
  38. client_event_cb(struct bufferevent *bev, short events, void *ctx)
  39. {
  40.         if (events & BEV_EVENT_ERROR)
  41.                 perror("Error from bufferevent");
  42.         if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
  43.                 bufferevent_free(bev);
  44.         }
  45. }
  46.  
  47. static void
  48. accept_conn_cb(struct evconnlistener *listener,
  49.                 evutil_socket_t fd, struct sockaddr *address, int socklen,
  50.                 void *ctx)
  51. {
  52.         struct event_base *base = evconnlistener_get_base(listener);
  53.         struct bufferevent *bev = bufferevent_socket_new(
  54.                         base, fd, BEV_OPT_CLOSE_ON_FREE);
  55.  
  56.         bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);
  57.  
  58.         bufferevent_enable(bev, EV_READ|EV_WRITE);
  59. }
  60.  
  61. static void
  62. client_incoming_socket_cb( struct bufferevent *bev, void *ctx )
  63. {
  64.         char recv_msg[256];
  65.         memset(recv_msg, 0, 256);
  66.         bufferevent_read( bev, recv_msg, sizeof(recv_msg));
  67.  
  68.         fprintf( stderr, "Incoming message from Server to Client = '%s'\n", recv_msg );
  69.  
  70.         fprintf( stderr, "Simulating Client CUTOFF\n" );
  71.         struct event_base *base = (struct event_base*) ctx;
  72.         event_base_loopexit( base, NULL );
  73. }
  74.  
  75. static void
  76. accept_error_cb(struct evconnlistener *listener, void *ctx)
  77. {
  78.         struct event_base *base = evconnlistener_get_base(listener);
  79.         int err = EVUTIL_SOCKET_ERROR();
  80.         fprintf(stderr, "Got an error %d (%s) on the listener. "
  81.                         "Shutting down.\n", err, evutil_socket_error_to_string(err));
  82.  
  83.         event_base_loopexit(base, NULL);
  84. }
  85.  
  86. static void* startServer( void* userData )
  87. {
  88.         struct event_base *base;
  89.         struct evconnlistener *listener;
  90.         struct sockaddr_in sin;
  91.  
  92.         int port = 7777;
  93.  
  94.         base = event_base_new();
  95.         if (!base) {
  96.                 puts("Couldn't open event base");
  97.                 return NULL;
  98.         }
  99.  
  100.         memset(&sin, 0, sizeof(sin));
  101.         sin.sin_family = AF_INET;
  102.         sin.sin_addr.s_addr = htonl(0);
  103.         sin.sin_port = htons(port);
  104.  
  105.         listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
  106.                         LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
  107.                         (struct sockaddr*)&sin, sizeof(sin));
  108.         if (!listener) {
  109.                 perror("Couldn't create listener");
  110.                 return NULL;
  111.         }
  112.         evconnlistener_set_error_cb(listener, accept_error_cb);
  113.  
  114.         event_base_dispatch(base);
  115.         return NULL;
  116. }
  117.  
  118. static void* startClient( void* userData )
  119. {
  120.         int port = 7777;
  121.         struct sockaddr_in sin;
  122.         int sockfd;
  123.  
  124.         bzero( &sin, sizeof( sin ));
  125.         sin.sin_family      = AF_INET;
  126.         sin.sin_addr.s_addr = inet_addr( "127.0.0.1" );
  127.         sin.sin_port        = htons( port );
  128.         if ( (sockfd=socket( PF_INET, SOCK_STREAM, IPPROTO_TCP )) < 0 )      // AF_INET also seems to work
  129.         {
  130.                 perror( "socket() failed: " );
  131.                 exit( -1 );
  132.         }
  133.         if ( (connect( sockfd, (struct sockaddr *) &sin, sizeof(sin))) < 0 )
  134.         {
  135.                 perror( "connect() failed: " );
  136.                 exit( -1 );
  137.         }
  138.  
  139.         struct event_base*  base = event_base_new();
  140.         struct bufferevent* bev = bufferevent_socket_new( base, sockfd, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE );
  141.         bufferevent_enable( bev, EV_READ|EV_WRITE );
  142.         bufferevent_setcb(  bev, client_incoming_socket_cb, NULL, client_event_cb, base );
  143.  
  144.         const char* str = "Hello World!";
  145.         evbuffer_add( bufferevent_get_output( bev ), str, strlen( str ));
  146.  
  147.         event_base_dispatch(base);
  148.         return NULL;
  149. }
  150.  
  151. int
  152. main(int argc, char **argv)
  153. {
  154.         evthread_use_pthreads();
  155.  
  156.         pthread_t a, b;
  157.  
  158.         pthread_create( &a, NULL, startServer, NULL );
  159.         usleep( 5000 );  // wait a bit for the server to come up
  160.         pthread_create( &b, NULL, startClient, NULL );
  161.  
  162.         pthread_join( a, NULL );
  163.         pthread_join( b, NULL );
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement