Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef _WIN32
- # define WIN32
- #endif
- #include <event2/util.h>
- #include <event2/event.h>
- #include <event2/buffer.h>
- #include <event2/thread.h>
- #include <event2/listener.h>
- #include <event2/bufferevent.h>
- #include <assert.h>
- #ifdef _WIN32
- # define WINDOWS_LEAN_AND_MEAN 1
- #include <WinSock2.h>
- #include <Windows.h>
- #endif
- #define USE_IOCP 0
- struct event_base* eventBase = NULL;
- //**********************************************************************
- // Server side simulation.
- //**********************************************************************
- void serverReadCallback( struct bufferevent *bev, void *ctx )
- {
- (void)bev; (void)ctx;
- struct evbuffer* input = bufferevent_get_input( bev );
- evbuffer_drain( input, evbuffer_get_length( input ) );
- }
- void serverWriteCallback( struct bufferevent *bev, void* )
- {
- struct evbuffer* output = bufferevent_get_output( bev );
- assert( evbuffer_get_length( output )==0 );
- shutdown( bufferevent_getfd( bev ), SD_SEND );
- }
- void serverEventCallback( struct bufferevent *bev, short what, void *ctx )
- {
- (void)bev; (void)what; (void)ctx;
- switch( what )
- {
- case BEV_EVENT_EOF | BEV_EVENT_READING:
- printf( "Server: Read EOF\n" );
- bufferevent_free( bev );
- event_base_loopexit( eventBase, NULL );
- break;
- case BEV_EVENT_EOF | BEV_EVENT_WRITING:
- printf( "Server: Write EOF\n" );
- break;
- }
- }
- //**********************************************************************
- // Client side simulation.
- //**********************************************************************
- void clientReadCallback( struct bufferevent *bev, void * )
- {
- // Going to bounce the data back to the server side.
- struct evbuffer* input = bufferevent_get_input( bev );
- struct evbuffer* output = bufferevent_get_output( bev );
- evbuffer_add_buffer( output, input );
- bufferevent_setwatermark( bev, EV_WRITE, 1, 0 );
- }
- void clientWriteCallback( struct bufferevent *bev, void *ctx )
- {
- (void)bev; (void)ctx;
- shutdown( bufferevent_getfd( bev ), SD_SEND );
- }
- void clientEventCallback( struct bufferevent *bev, short what, void *ctx )
- {
- (void)bev; (void)what; (void)ctx;
- switch( what )
- {
- case BEV_EVENT_EOF | BEV_EVENT_READING:
- printf( "Client: Read EOF\n" );
- bufferevent_free( bev );
- break;
- case BEV_EVENT_EOF | BEV_EVENT_WRITING:
- printf( "Client: Write EOF\n" );
- break;
- case BEV_EVENT_CONNECTED:
- printf( "Client: Connected\n" );
- break;
- }
- }
- //**********************************************************************
- // Listener callback.
- //**********************************************************************
- void listenerCallback( struct evconnlistener* el, evutil_socket_t fd, struct sockaddr* addr, int addrLen, void* context )
- {
- (void)el;
- (void)addr;
- (void)addrLen;
- (void)context;
- struct bufferevent* servEvent = bufferevent_socket_new( eventBase, fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE );
- // Send some trash data and prepare to shutdown.
- int trash[] = {1, 2, 3, 4};
- struct evbuffer* output = bufferevent_get_output( servEvent );
- evbuffer_iovec ioVec;
- evbuffer_reserve_space( output, sizeof( trash ), &ioVec, 1 );
- ::memcpy( ioVec.iov_base, trash, sizeof( trash ) );
- ioVec.iov_len = sizeof( trash );
- evbuffer_commit_space( output, &ioVec, 1 );
- bufferevent_setwatermark( servEvent, EV_WRITE, 1, 0 );
- bufferevent_setcb( servEvent, &serverReadCallback, &serverWriteCallback, &serverEventCallback, NULL );
- bufferevent_enable( servEvent, EV_READ | EV_WRITE );
- }
- extern "C"
- int main( const int argc, const char** argv )
- {
- (void)argc; (void)argv;
- static const int kPort = 4013;
- #ifdef _WIN32
- WSADATA wsaData;
- if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData )!=0 )
- return -1;
- #endif
- #if _WIN32
- if( evthread_use_windows_threads() != 0 )
- return -1;
- #else
- if( evthread_use_pthreads() != 0 )
- return -1;
- #endif
- // Bring up the event base potentially with IOCP.
- struct event_config* eventConfig = event_config_new();
- #ifdef _WIN32
- # if USE_IOCP
- event_config_set_flag( eventConfig, EVENT_BASE_FLAG_STARTUP_IOCP );
- # endif
- #endif
- eventBase = event_base_new_with_config( eventConfig );
- event_config_free( eventConfig );
- // Bring up a local listener.
- struct sockaddr_in listenAddr;
- ::memset( &listenAddr, 0, sizeof( listenAddr ) );
- listenAddr.sin_addr.s_addr = 0;
- listenAddr.sin_port = htons( 4013 );
- listenAddr.sin_family = AF_INET;
- struct evconnlistener* listener = evconnlistener_new_bind(
- eventBase,
- &listenerCallback,
- NULL,
- LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
- -1,
- (const sockaddr*)&listenAddr,
- sizeof( listenAddr ) );
- // Bring up the socket which will connect to listener.
- struct sockaddr_in connectAddr;
- ::memset( &connectAddr, 0, sizeof( connectAddr ) );
- connectAddr.sin_addr.s_addr = htonl(0x7f000001);
- connectAddr.sin_port = htons( kPort );
- connectAddr.sin_family = AF_INET;
- struct bufferevent* clientConnection = bufferevent_socket_new( eventBase, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE );
- bufferevent_socket_connect( clientConnection, (sockaddr*)&connectAddr, sizeof( connectAddr ) );
- bufferevent_setcb( clientConnection, &clientReadCallback, &clientWriteCallback, &clientEventCallback, NULL );
- bufferevent_enable( clientConnection, EV_READ | EV_WRITE );
- // Run the dispatch.
- while( event_base_dispatch( eventBase )==1 )
- ;
- evconnlistener_free( listener );
- event_base_free( eventBase );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement