看了好几天总算看懂了libevent.
测试稳定代码如下:
Win32NetWork.h:
#ifndef WIN32NETWORK_H #define WIN32NETWORK_H //#include <WinSock.h> #pragma comment(lib,"ws2_32.lib") class CWin32NetWork{ public: CWin32NetWork(){ WSADATA wsa_data; WSAStartup(0x0201, &wsa_data); } }; #endif
#include <event2/bufferevent.h> #include <event2/buffer.h> #include <event2/listener.h> #include <event2/util.h> #include <event2/event.h> #pragma comment(lib,"libevent.lib") #include "..\NetWork\Win32NetWork.h" #include <stdio.h> #include <event.h> CWin32NetWork network; #define PORT 25341 #define BACKLOG 5 #define MEM_SIZE 1024 struct event_base* base; //读写事件结构体 struct sock_ev { struct event* read_ev; struct event* write_ev; char* buffer; }; //释放句柄资源 void release_sock_event(struct sock_ev* ev) { //event_del(ev->read_ev); event_del_noblock(ev->read_ev); free(ev->read_ev); free(ev->write_ev); if(ev->buffer != NULL) free(ev->buffer); free(ev); } //申请句柄资源 struct sock_ev* malloc_sock_event(){ struct sock_ev* ev = (struct sock_ev*)malloc(sizeof(struct sock_ev)); ev->read_ev = (struct event*)malloc(sizeof(struct event)); ev->write_ev = (struct event*)malloc(sizeof(struct event)); ev->buffer = NULL; return ev; } //释放事件回调方法 void on_free(struct event *ev, void *arg) { struct sock_ev* sockEv = (struct sock_ev*)arg; release_sock_event(sockEv); } //发送数据回调方法 void on_write(int sock, short event, void* arg) { struct sock_ev* ev = (struct sock_ev*)arg; if(ev == NULL) return; char* buffer = (char*)ev->buffer; if(buffer != NULL) send(sock, buffer, strlen(buffer), 0); } //读取数据回调方法 void on_read(int sock, short event, void* arg) { int size; struct sock_ev* ev = (struct sock_ev*)arg; if(ev->buffer == NULL) ev->buffer = (char*)malloc(MEM_SIZE); ZeroMemory(ev->buffer, MEM_SIZE); size = recv(sock, ev->buffer, MEM_SIZE, 0); //printf("receive data:%s, size:%d\n", ev->buffer, size); if (size <= 0) { //释放掉事件资源 ev->read_ev->ev_evcallback.evcb_arg = arg; event_finalize(0,ev->read_ev,on_free); closesocket(sock); return; } event_set(ev->write_ev, sock, EV_WRITE, on_write, ev); event_base_set(base, ev->write_ev); event_add(ev->write_ev, NULL); } //接收连接回调函数 void on_accept(int sock, short event, void* arg) { struct sockaddr_in cli_addr; int newfd, sin_size; struct sock_ev* ev = malloc_sock_event(); sin_size = sizeof(struct sockaddr_in); newfd = accept(sock, (struct sockaddr*)&cli_addr, &sin_size); event_set(ev->read_ev, newfd, EV_READ|EV_PERSIST, on_read, ev); event_base_set(base, ev->read_ev); event_add(ev->read_ev, NULL); } int main(int argc, char* argv[]) { struct sockaddr_in my_addr; int sock; sock = socket(AF_INET, SOCK_STREAM, 0); int yes = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int)); memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = INADDR_ANY; bind(sock, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)); listen(sock, BACKLOG); struct event listen_ev; base = event_base_new(); event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL); event_base_set(base, &listen_ev); event_add(&listen_ev, NULL); event_base_dispatch(base); return 0; }