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.

217 lines
5.8 KiB

  1. #include <iostream>
  2. #include <event2/event.h>
  3. #include <event2/thread.h>
  4. #include <event2/listener.h>
  5. #include <event2/bufferevent.h>
  6. #ifdef _WIN32
  7. #include <string>
  8. #else
  9. #include <signal.h>
  10. #include <string.h>
  11. #endif // !_WIN32
  12. using namespace std;
  13. static string recvstr = "";
  14. static int recvCount = 0;
  15. static int sendCount = 0;
  16. void read_cb(bufferevent * bev, void *arg) {
  17. cout << "[R]" << endl;
  18. char data[1024] = { 0 };
  19. int len = bufferevent_read(bev, data, sizeof(data) - 1);
  20. if (len <= 0)return;
  21. recvstr += data;
  22. recvCount += len;
  23. /* if(strstr(data,"quit")!= NULL){
  24. cout << "quit" << endl;
  25. bufferevent_free(bev); // BEV_OPT_CLOSE_ON_FREE 设置了这个才会关闭
  26. } */
  27. //发送数据 写入到输出缓冲
  28. bufferevent_write(bev, "ok", 3);
  29. }
  30. void write_cb(bufferevent * bev, void *arg) {
  31. cout << "[W]" << endl;
  32. }
  33. //错误 超时 连接断开会进入
  34. void event_cb(struct bufferevent *bev, short what, void *ctx) {
  35. cout << "[CB]" << endl;
  36. //读取超时事件发生后,数据读取停止
  37. if (what & BEV_EVENT_TIMEOUT && what & BEV_EVENT_READING) {
  38. char data[1024] = { 0 };
  39. int len = bufferevent_read(bev, data, sizeof(data) - 1);
  40. if (len > 0) {
  41. recvCount += len;
  42. recvstr += data;
  43. }
  44. cout << "read timeout " << endl;
  45. //bufferevent_enable(bev,EV_READ); //可以重新设置
  46. bufferevent_free(bev);
  47. cout << recvstr << endl;
  48. cout << "recvCOunt" << recvCount << " sendCount" << sendCount << endl;
  49. }
  50. else if (what & BEV_EVENT_ERROR) {
  51. bufferevent_free(bev);
  52. }
  53. else {
  54. cout << "other " << endl;
  55. }
  56. }
  57. void listen_cb(struct evconnlistener *ev, evutil_socket_t s,
  58. struct sockaddr *insin, int socklen, void *arg)
  59. {
  60. cout << "listen_cb" << endl;
  61. struct sockaddr_in *sin = (struct sockaddr_in *)&insin;
  62. int port = ntohs(sin->sin_port);
  63. char ip[16] = { 0 };
  64. evutil_inet_ntop(AF_INET, &sin->sin_addr, ip, sizeof(ip) - 1);
  65. cout << "client ip is " << ip << "port is " << port << endl;
  66. event_base* base = (event_base*)arg;
  67. //创建bufferevent上下文 BEV_OPT_CLOSE_ON_FREE清理bufferevent时关闭socket
  68. bufferevent * bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE);
  69. bufferevent_enable(bev, EV_READ | EV_WRITE);
  70. //设置水位
  71. //读取水位
  72. bufferevent_setwatermark(bev, EV_READ,
  73. 10, //低水位0就是无限制 默认0 有10个数据才会回调函数被调用
  74. 10); //高水位0就是无限制 默认0 超过10的数据会拆分成多个10调用多次
  75. bufferevent_setwatermark(bev, EV_WRITE,
  76. 5, // 低水位0就是无限制 默认0 缓冲数据低于5 写入回调内调用
  77. 0); //暂时无效
  78. timeval t1 = { 0,50000 };
  79. bufferevent_set_timeouts(bev, &t1, NULL);
  80. bufferevent_setcb(bev, read_cb, write_cb, event_cb, base);
  81. }
  82. void clinet_read_cb(bufferevent * bev, void *arg) {
  83. cout << "[clinet R]" << endl;
  84. char data[1024] = { 0 };
  85. int len = bufferevent_read(bev, data, sizeof(data) - 1);
  86. if (len <= 0)return;
  87. cout << "[" << data << "]" << endl;
  88. /* if(strstr(data,"quit")!= NULL){
  89. cout << "quit" << endl;
  90. bufferevent_free(bev); // BEV_OPT_CLOSE_ON_FREE 设置了这个才会关闭
  91. } */
  92. //发送数据 写入到输出缓冲
  93. //bufferevent_write(bev,"ok",3);
  94. }
  95. void clinet_write_cb(bufferevent * bev, void *arg) {
  96. cout << "[clinet W]" << endl;
  97. //激活write
  98. FILE *fp = (FILE *)arg;
  99. char data[1024] = { 0 };
  100. int len = fread(data, 1, sizeof(data) - 1, fp);
  101. if (len <= 0) {
  102. // 读到文件结尾或者文件出错
  103. fclose(fp);
  104. //立刻清理 可能会造成缓冲数据没有发送结束 !! 不能在这里做
  105. //bufferevent_free(bev);
  106. bufferevent_disable(bev, EV_WRITE);
  107. return;
  108. }
  109. sendCount += len;
  110. bufferevent_write(bev, data, len);
  111. }
  112. //错误 超时 连接断开会进入
  113. void clinet_event_cb(struct bufferevent *bev, short what, void *ctx) {
  114. cout << "[ clinet CB]" << endl;
  115. //读取超时事件发生后,数据读取停止
  116. if (what & BEV_EVENT_TIMEOUT && what & BEV_EVENT_READING) {
  117. cout << "read timeout " << endl;
  118. //bufferevent_enable(bev,EV_READ); //可以重新设置
  119. bufferevent_free(bev);
  120. return;
  121. }
  122. else if (what & BEV_EVENT_ERROR) {
  123. bufferevent_free(bev);
  124. return;
  125. }
  126. //服务端的关闭事件
  127. if (what & BEV_EVENT_EOF) {
  128. cout << "BEV_EVENT_EOF" << endl;
  129. bufferevent_free(bev);
  130. }
  131. if (what & BEV_EVENT_CONNECTED) {
  132. cout << "BEV_EVENT_CONNECTED " << endl;
  133. bufferevent_trigger(bev, EV_WRITE, 0); //触发写事件
  134. }
  135. }
  136. int main(int agrc, char **agrv)
  137. {
  138. #ifdef _WIN32
  139. //初始化socket库
  140. WSADATA wsa;
  141. WSAStartup(MAKEWORD(2, 2), &wsa);
  142. #else
  143. if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
  144. { //忽略管道信号,发送数据给已关闭的socket,会飞掉!
  145. return 1;
  146. }
  147. #endif
  148. //创建网络服务器
  149. event_base *base = event_base_new();
  150. sockaddr_in sin;
  151. memset(&sin, 0, sizeof(sin));
  152. sin.sin_family = AF_INET;
  153. sin.sin_port = htons(5001);
  154. evconnlistener_new_bind(base,
  155. listen_cb,
  156. base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
  157. 10,
  158. (sockaddr *)&sin,
  159. sizeof(sin));
  160. { //防止变量名重定义
  161. //调用客户端代码
  162. // -1 内部创建socket
  163. bufferevent * bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
  164. sockaddr_in sin;
  165. memset(&sin, 0, sizeof(sin));
  166. sin.sin_family = AF_INET;
  167. sin.sin_port = htons(5001);
  168. evutil_inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr.s_addr);
  169. FILE *fp = fopen("test_buffer_client.cpp", "rb");
  170. //设置回调函数
  171. bufferevent_setcb(bev, clinet_read_cb, clinet_write_cb, clinet_event_cb, fp);
  172. bufferevent_enable(bev, EV_READ | EV_WRITE);
  173. int ret = bufferevent_socket_connect(bev, (sockaddr*)&sin, sizeof(sin));
  174. if (ret == 0) {
  175. cout << "connected" << endl;
  176. }
  177. }
  178. //进入事件主循环
  179. event_base_dispatch(base);
  180. event_base_free(base);
  181. return 0;
  182. }