You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.8 KiB

  1. #include <iostream>
  2. #include <event2/event.h>
  3. #include <string.h>
  4. #include <thread>
  5. #include <errno.h>
  6. #define SPORT 5001
  7. #ifdef _WIN32
  8. #else
  9. #include <signal.h>
  10. #endif // !_WIN32
  11. using namespace std;
  12. //正常断开连接也会进入 超时会进入
  13. void client_cb(evutil_socket_t s,short w,void *arg){
  14. //水平触发LT 只要有数据没处理会 一直进入
  15. //边缘触发ET 有数据时只触发一次
  16. event *ev = (event *) arg;
  17. if(w&EV_TIMEOUT){
  18. cout << "timeout" << endl;
  19. //需要清理event
  20. event_free(ev);
  21. evutil_closesocket(s);
  22. return;
  23. }
  24. char buf[1024]= {0};
  25. int len = recv(s,buf,sizeof(buf)-1,0);
  26. if(len > 0){
  27. cout << buf << flush;
  28. send(s,"ok",2,0);
  29. }
  30. else{
  31. //需要清理event
  32. cout << "event_free" << endl;
  33. event_free(ev);
  34. evutil_closesocket(s);
  35. }
  36. }
  37. void listen_cb(evutil_socket_t s,short w,void *arg){
  38. cout << "listen_cb" << endl;
  39. sockaddr_in sin;
  40. socklen_t size = sizeof(sin);
  41. //读取连接信息
  42. evutil_socket_t client = accept(s,(sockaddr*)&sin,&size);
  43. char ip[16] = {0};
  44. evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1);
  45. cout << "client ip is " << ip << endl;
  46. //客户端数据读取事件
  47. event_base *base = (event_base*)arg;
  48. event *ev = event_new(base,client,EV_READ|EV_PERSIST ,client_cb,event_self_cbarg());
  49. timeval t = {10,0};
  50. event_add(ev,&t);
  51. }
  52. int main(int agrc,char** agrv){
  53. #ifdef _WIN32
  54. //初始化socket库
  55. WSADATA wsa;
  56. WSAStartup(MAKEWORD(2, 2), &wsa);
  57. #else
  58. if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { //忽略管道信号,发送数据给已关闭的socket,会飞掉!
  59. return 1;
  60. }
  61. #endif
  62. event_base *base = event_base_new();
  63. cout << "test event server" << endl;
  64. evutil_socket_t sock = socket(AF_INET,SOCK_STREAM,0);
  65. if(sock == 0){
  66. cout << "socket error:" << strerror(errno) << endl;
  67. return -1;
  68. }
  69. //绑定端口地址
  70. sockaddr_in sin;
  71. memset(&sin,0,sizeof(sin));
  72. sin.sin_family = AF_INET;
  73. sin.sin_port = htons(SPORT);
  74. int re = ::bind(sock,(sockaddr*)&sin,sizeof(sin));
  75. if(re != 0){
  76. cerr << "bind error: " << strerror(errno) << endl;
  77. return -1;
  78. }
  79. //设置地址复用和非阻塞
  80. evutil_make_socket_nonblocking(sock);
  81. evutil_make_listen_socket_reuseable(sock);
  82. //开始监听
  83. listen(sock,10);
  84. //开始接收连接事件
  85. event *ev = event_new(base,sock,EV_READ|EV_PERSIST /* |EV_ET*/ ,listen_cb,base); //默认水平触发
  86. event_add(ev,0);
  87. //进入事件主循环
  88. event_base_dispatch(base);
  89. evutil_closesocket(sock);
  90. event_base_free(base);
  91. return 0;
  92. }