Browse Source

网路服务器事件监听

master
adminPyf 3 years ago
parent
commit
aae17206ac
2 changed files with 116 additions and 0 deletions
  1. +2
    -0
      test_event_server/makefile
  2. +114
    -0
      test_event_server/test_event_server.cpp

+ 2
- 0
test_event_server/makefile View File

@ -0,0 +1,2 @@
test_event_server:test_event_server.cpp
g++ $^ -o $@ -levent

+ 114
- 0
test_event_server/test_event_server.cpp View File

@ -0,0 +1,114 @@
#include <iostream>
#include <event2/event.h>
#include <string.h>
#include <thread>
#include <errno.h>
#define SPORT 5001
#ifdef _WIN32
#else
#include <signal.h>
#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;
}

Loading…
Cancel
Save