libevent source analysis (a)

 

/ * 
  Version: 2.1.11 
  source location: the Sample / the Hello-world.c 

  This Example Program Program that the Provides A Trivial Server Listens for TCP 
  Connections Port 9995. ON the When They arrive, IT A Short Writes the Message to 
  the each Client Connection, and Closes . each connection once it is flushed 
  this example provides a small server program: TCP listening on port 9995. 
  When a connection request arrives, write back a string, when the write buffer refresh immediately disconnected. 
  Possible WHERE, IT exits cleanly in Response to A SIGINT (Ctrl-c). 
  Ctrl + c After transmission SIGINT signal, the response signal and the program ends. 
* / 


#Include < String .h> 
#include <errno.h> 
#include <stdio.h> 
#include <signal.h> 
#ifndef _WIN32 
#include<the netinet / in .h> 
#ifdef _XOPEN_SOURCE_EXTENDED 
#include <ARPA / inet.h>
 #endif 
#include <SYS / socket.h>
 #endif 

#include <Event2 / bufferevent.h> 
#include <Event2 / buffer.h> 
#include <Event2 / listener.h> 
#include <Event2 / util.h> 
#include <Event2 / Event .h> / * 
from the following user-defined data,: 
    same as static data type definitions; * / static const char the MESSAGE [] = " the Hello, World \ n-! " ; static const int PORT =





  

  9995 ; 

// listener callback 
static  void listener_cb ( struct evconnlistener * , evutil_socket_t,
     struct sockaddr *, int socklen, void * );
 // write callback 
static  void conn_writecb ( struct bufferevent *, void * );
 // error callback 
static  void conn_eventcb ( struct bufferevent *, Short , void * );
 // signal event callbacks 
static  voidsignal_cb (evutil_socket_t, Short , void * ); 

int 
main ( int argc, char ** the argv) 
{ 
    struct event_base * Base ;
     struct evconnlistener * listener;
     struct  Event * signal_event; 

    struct the sockaddr_in SiN; 
#ifdef _WIN32 
    WSADATA wsa_data; 
    WSAStartup ( 0x0201 , & wsa_data);
 #endif 

    // 1. create event_base, for monitoring and activation of pending events event 
    Base = event_base_new ();
     IF(! Base ) { 
        fprintf (stderr, " Could Not the initialize the libevent \ n-! " );
         Return  . 1 ; 
    } 
    // 2. server address 
    Memset (& SiN, 0 , the sizeof (SiN)); 
    sin.sin_family = AF_INET; 
    SiN. sin_port = htons (PORT); 

    // 3. create a listener 
    listener = evconnlistener_new_bind ( Base , listener_cb, ( void *) Base , 
        LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, - 1 , 
        (struct the sockaddr *) & SiN,
         the sizeof (SiN)); 

    IF ! ( listener) { 
        fprintf (stderr, " ! Could Not Create A listener \ n- " );
         return  . 1 ; 
    } 
    // 4. Create an event signal 
    signal_event = evsignal_new ( Base , SIGINT, signal_cb, ( void *) Base );
     // 5. the signal event is added to the scheduling loop 
    IF <(signal_event || event_add (signal_event, NULL!) 0 ) { 
        fprintf (stderr, " Could Not Create / the Add ! A Signal Event \ the n- " );
        return  . 1 ; 
    } 
    // 6. The open loop scheduling, monitoring pending events 
    event_base_dispatch ( Base );
     // 7. The release resources 
    evconnlistener_free (listener); 
    event_free (signal_event); 
    event_base_free ( Base ); 

    the printf ( " DONE \ n- " ) ;
     return  0 ; 
} 

static  void 
listener_cb ( struct evconnlistener * listener, evutil_socket_t FD,
     struct the sockaddr SA *, int socklen, void * the user_data) 
{
    struct event_base *base = user_data;
    struct bufferevent *bev;

    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (!bev) {
        fprintf(stderr, "Error constructing bufferevent!");
        event_base_loopbreak(base);
        return;
    }
    bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
    bufferevent_enable(bev, EV_WRITE);
    bufferevent_disable(bev, EV_READ);

    bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}

static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
    struct evbuffer *output = bufferevent_get_output(bev);
    if (evbuffer_get_length(output) == 0) {
        printf("flushed answer\n");
        bufferevent_free(bev);
    }
}

static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
    if (events & BEV_EVENT_EOF) {
        printf("Connection closed.\n");
    } else if (events & BEV_EVENT_ERROR) {
        printf("Got an error on the connection: %s\n",
            strerror(errno));/*XXX win32*/
    }
    /* None of the other events can happen here, since we haven't enabled
     * timeouts */
    bufferevent_free(bev);
}

static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
    struct event_base *base = user_data;
    struct timeval delay = { 2, 0 };

    printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");

    event_base_loopexit(base, &delay);
}

 

 

 

  

 

Guess you like

Origin www.cnblogs.com/orejia/p/12348969.html