#include <iostream>
#include <stdio.h>
#include <signal.h>
#ifndef WIN32
#include <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"
#include <WinSock2.h>
static const char MESSAGE[] = "Hello, World!\n" ;
static const int PORT = 9995;
static void conn_writecb( struct bufferevent *bev, void *user_data )
{
std::cout << __LINE__ << " 回调函数: conn_writecb " << std::endl ;
struct evbuffer *output = bufferevent_get_output(bev );
if (evbuffer_get_length (output) == 0)
{
printf("flushed answer\n" );
}
}
static void conn_readcb( struct bufferevent *bev, void *user_data )
{
std::cout << __LINE__ << " 回调函数:conn_readcb" << std::endl ;
char buf[1024];
int n;
struct evbuffer *input = bufferevent_get_input(bev); // 得到读取缓冲区
while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0) // 移动input 中的数据到buf 空间。
fwrite(buf, 1, n, stdout);
}
static void conn_eventcb( struct bufferevent *bev, short events , void *user_data)
{
std::cout << __LINE__ << " 回调函数:conn_eventcb" << std::endl ;
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)
{
std::cout << __LINE__ << " 回调函数:signal_cb" << std::endl ;
struct event_base *base = ( struct event_base *)user_data;
struct timeval delay = { 2, 0 };
printf("Caught an interrupt signal; exiting cleanly in two seconds.\n" );
event_base_loopexit(base , &delay);
}
static void listener_cb( struct evconnlistener *listener, evutil_socket_t fd ,
struct sockaddr *sa, int socklen , void * user_data)
{
std::cout << __LINE__ << " 回调函数:listener_cb" << std::endl ;
struct event_base *base = ( struct event_base *)user_data;
struct bufferevent *bev;
// 构造一个与fd 连接者的bufferevent,使用该bufferevent 对象来与对端进行数据通信
// 并且设置(BEV_OPT_CLOSE_ON_FREE)
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 , conn_readcb, conn_writecb, conn_eventcb , NULL);
bufferevent_enable(bev , EV_READ | EV_WRITE);
// 发送数据
bufferevent_write(bev , MESSAGE, strlen(MESSAGE));
}
int main (int argc, char **argv)
{
#ifdef WIN32
WSADATA wsa_data ;
WSAStartup(0x0201, &wsa_data );
#endif
struct event_base *base;
base = event_base_new ();
if (!base )
{
fprintf(stderr , "Could not initialize libevent!\n");
return 1;
}
struct sockaddr_in sin;
memset(&sin , 0, sizeof( sin));
sin.sin_family = AF_INET;
sin.sin_port = htons( PORT);
// 创建监听器
struct evconnlistener *listener;
listener = evconnlistener_new_bind (base, listener_cb, (void *)base,
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE , -1,
( struct sockaddr *)&sin,
sizeof(sin ));
if (!listener )
{
fprintf(stderr , "Could not create a listener!\n");
return 1;
}
// 注册信号事件
struct event *signal_event;
signal_event = evsignal_new (base, SIGINT, signal_cb , (void *) base);
if (!signal_event || event_add( signal_event, NULL )<0)
{
fprintf(stderr , "Could not create/add a signal event!\n");
return 1;
}
// 开始事件循环
event_base_dispatch(base );
evconnlistener_free(listener );
event_free(signal_event );
event_base_free(base );
printf("done\n" );
return 0;
}
libevent 服务器代码,简单的整理。
最新推荐文章于 2023-02-06 22:41:40 发布