diff --git a/test_event_server/makefile b/test_event_server/makefile new file mode 100644 index 0000000..7338cff --- /dev/null +++ b/test_event_server/makefile @@ -0,0 +1,2 @@ +test_event_server:test_event_server.cpp + g++ $^ -o $@ -levent \ No newline at end of file diff --git a/test_event_server/test_event_server.cpp b/test_event_server/test_event_server.cpp new file mode 100644 index 0000000..26a0c26 --- /dev/null +++ b/test_event_server/test_event_server.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include + +#define SPORT 5001 +#ifdef _WIN32 + +#else + #include +#endif // !_WIN32 + +using namespace std; +//正常断开连接也会进入 超时会进入 +void client_cb(evutil_socket_t s,short w,void *arg){ + //水平触发LT 只要有数据没处理会 一直进入 + //边缘触发ET 有数据时只触发一次 + event *ev = (event *) arg; + if(w&EV_TIMEOUT){ + cout << "timeout" << endl; + //需要清理event + event_free(ev); + evutil_closesocket(s); + return; + } + + char buf[1024]= {0}; + int len = recv(s,buf,sizeof(buf)-1,0); + if(len > 0){ + cout << buf << flush; + send(s,"ok",2,0); + } + else{ + //需要清理event + cout << "event_free" << endl; + event_free(ev); + evutil_closesocket(s); + } + +} + + +void listen_cb(evutil_socket_t s,short w,void *arg){ + cout << "listen_cb" << endl; + + sockaddr_in sin; + socklen_t size = sizeof(sin); + //读取连接信息 + evutil_socket_t client = accept(s,(sockaddr*)&sin,&size); + char ip[16] = {0}; + evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1); + cout << "client ip is " << ip << endl; + + //客户端数据读取事件 + event_base *base = (event_base*)arg; + event *ev = event_new(base,client,EV_READ|EV_PERSIST ,client_cb,event_self_cbarg()); + + timeval t = {10,0}; + + event_add(ev,&t); +} + +int main(int agrc,char** agrv){ +#ifdef _WIN32 + //初始化socket库 + WSADATA wsa; + WSAStartup(MAKEWORD(2, 2), &wsa); +#else + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { //忽略管道信号,发送数据给已关闭的socket,会飞掉! + return 1; + } +#endif + + event_base *base = event_base_new(); + + cout << "test event server" << endl; + + evutil_socket_t sock = socket(AF_INET,SOCK_STREAM,0); + if(sock == 0){ + cout << "socket error:" << strerror(errno) << endl; + return -1; + } + + //绑定端口地址 + sockaddr_in sin; + memset(&sin,0,sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(SPORT); + int re = ::bind(sock,(sockaddr*)&sin,sizeof(sin)); + if(re != 0){ + cerr << "bind error: " << strerror(errno) << endl; + return -1; + } + + //设置地址复用和非阻塞 + evutil_make_socket_nonblocking(sock); + evutil_make_listen_socket_reuseable(sock); + + //开始监听 + listen(sock,10); + + //开始接收连接事件 + event *ev = event_new(base,sock,EV_READ|EV_PERSIST /* |EV_ET*/ ,listen_cb,base); //默认水平触发 + event_add(ev,0); + + //进入事件主循环 + event_base_dispatch(base); + evutil_closesocket(sock); + event_base_free(base); + + return 0; + +} \ No newline at end of file