前段时间一个项目需要用到高并发的服务,想着自己应该可以写一个,windwos 上使用完成端口实现,写完之后,测试感觉没什么问题,可是一上线各种各样的问题,初步怀疑是底层网路库的问题,于是决定更换网络库,使用libevent
1,下载最新稳定版libevent
http://libevent.org/ 目前最新稳定版本应该是 下载解压目录
2,编译lib库
使用VS命令提示工具编译:
32位库的编译方法
cd F:\libevent\libevent-2.1.8-stable
nmake /f Makefile.nmake
会在根目录下生成三个文件libevent_core.lib,ibevent_extras.lib,libevent.lib
64位库的编译方法
首先修改Makefile.nmake 在LIBFLAGS=/nologo 后面加上 /MACHINE:X64
cd F:\libevent\libevent-2.1.8-stable
nmake /f Makefile.nmake
顺利的话,根目录下同样会生成一个64位的库文件,
3,使用lib库
新建一个lib文件夹,将上面编译好的lib文件放进去
新建一个Include目录,将F:\libevent\libevent-2.1.8-stable\include下的文件和文件夹copy到该目录下,F:\libevent\libevent-2.1.8-stable\WIN32-Code下的文件copy到该目录下,2个event2目录下的文件可合并一起。
然后,在项目工程中引用该include 和lib
#ifndef WIN32#include# ifdef _XOPEN_SOURCE_EXTENDED# include # endif#include #endif#include "event2/bufferevent.h"#include "event2/buffer.h"#include "event2/listener.h"#include "event2/util.h"#include "event2/event.h"#include string IP = "127.0.0.1";int PORT = 9500;char * pMessage = "hello client";struct bevdata{ string ip; int port;};static void conn_readcb(struct bufferevent *bev, void *ctx){ bevdata *pbev_data = (bevdata*)ctx; struct evbuffer* input = bufferevent_get_input(bev); size_t len = evbuffer_get_length(input); printf("point = %x,len = %d",bev,len); struct evbuffer* output = bufferevent_get_output(bev); char msg[4096] = { 0}; len = bufferevent_read(bev, msg, sizeof(msg) - 1); printf("server recv data : %s:%d %s\n",pbev_data->ip.c_str(),pbev_data->port,msg); char senddata[20]; strcpy(senddata,"i recv your data"); bufferevent_write(bev,senddata,strlen(senddata));}static void conn_writecb(struct bufferevent *bev, void *ctx){}static void conn_eventcb(struct bufferevent *bev, short what, void *ctx){ if (what & BEV_EVENT_EOF) { printf("connection closed\n"); } else if (what & BEV_EVENT_ERROR) { printf("some other error\n"); } bufferevent_free(bev);}static void signal_cb(evutil_socket_t sig, short events, void *user_data){ 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){ struct event_base * base = (struct event_base *)user_data; struct bufferevent * bev; bev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE); if(!bev) { printf("error constructing bufferevent\n"); event_base_loopbreak(base); return ; } char temp[1024] = { 0}; // 将sockaddr强制转换为 sockaddr_in sockaddr_in sin; memcpy(&sin, sa, sizeof(sin)); // 取得ip和端口号 sprintf(temp, inet_ntoa(sin.sin_addr)); bevdata *bev_data = new bevdata; bev_data->ip = temp; bev_data->port = sin.sin_port; printf("address = %s,port = %d,%x\n",temp,sin.sin_port,bev); bufferevent_setcb(bev,conn_readcb,conn_writecb,conn_eventcb,bev_data); bufferevent_enable(bev, EV_WRITE); bufferevent_enable(bev, EV_READ); bufferevent_write(bev,pMessage,strlen(pMessage));}int _tmain(int argc, _TCHAR* argv[]){ /*CCompleteIOWrapper complete ; complete.initComplete("127.0.0.1",9500); complete.startComplete(); getchar(); */ struct event_base * base; struct evconnlistener * listener; struct event * signal_event; struct sockaddr_in sin;#ifdef WIN32 WSADATA wsa_data; WSAStartup(0x0201,&wsa_data);#endif base = event_base_new(); if(!base) { printf("cannot initailize libevent\n"); return 1; } memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); sin.sin_addr.S_un.S_addr = inet_addr(IP.c_str()); 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) { printf("can not create a listener\n"); return 0; } signal_event = evsignal_new(base,SIGINT,signal_cb,(void*)base); if(!signal_event) { printf("can not create a signal event\n"); return 0; } printf("sertver starting...\n"); event_base_dispatch(base); evconnlistener_free(listener); event_free(signal_event); event_base_free(base); printf("done\n"); return 0;}
5,编译好的库文件,奉献给大家 https://files.cnblogs.com/files/techdreaming/lib.zip