#include <stdio.h>
#include <string.h>
#include <errno.h> #include <iostream>
using namespace std; #include <event2/event.h>
#include <event2/bufferevent.h> void accept_cb(int fd, short events, void* arg);
void socket_read_cb(bufferevent* bev, void* arg);
void event_cb(struct bufferevent *bev, short event, void *arg);
int tcp_server_init(int port, int listen_num); int main(int argc, char** argv)
{
#ifdef WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif int listener = tcp_server_init(9999, 10);
if( listener == -1 )
{
perror(" tcp_server_init error ");
return -1;
} struct event_base* base = event_base_new(); //添加监听客户端请求连接事件
struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST,
accept_cb, base);
event_add(ev_listen, NULL); event_base_dispatch(base);
event_base_free(base); #ifdef WIN32
WSACleanup();
#endif return 0;
} void accept_cb(int fd, short events, void* arg)
{
evutil_socket_t sockfd; struct sockaddr_in client;
int len = sizeof(client); sockfd = ::accept(fd, (struct sockaddr*)&client, &len );
evutil_make_socket_nonblocking(sockfd); cout << "accept a client " << sockfd << endl; struct event_base* base = (event_base*)arg; bufferevent* bev = bufferevent_socket_new(base, sockfd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, socket_read_cb, NULL, event_cb, arg); bufferevent_enable(bev, EV_READ | EV_PERSIST);
} void socket_read_cb(bufferevent* bev, void* arg)
{
char msg[4096] = {0}; size_t len = bufferevent_read(bev, msg, sizeof(msg)); cout << "recv the client msg: " << msg << endl;
// msg[len] = '\r';
// msg[len+1] = '\n'; char reply_msg[4096] = "I have recvieced the msg: "; strcat(reply_msg + strlen(reply_msg), msg);
bufferevent_write(bev, reply_msg, strlen(reply_msg));
} void event_cb(struct bufferevent *bev, short event, void *arg)
{ if (event & BEV_EVENT_EOF)
{
cout << "connection closed" << endl;
}
else if (event & BEV_EVENT_ERROR)
{
cout << "some other error" << endl;
} //这将自动close套接字和free读写缓冲区
bufferevent_free(bev);
} typedef struct sockaddr SA;
int tcp_server_init(int port, int listen_num)
{
evutil_socket_t listener; listener = ::socket(AF_INET, SOCK_STREAM, 0);
if( listener == -1 )
return -1; //允许多次绑定同一个地址。要用在socket和bind之间
evutil_make_listen_socket_reuseable(listener); do
{
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(port);
if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
break; if( ::listen(listener, listen_num) < 0)
break; //跨平台统一接口,将套接字设置为非阻塞状态
evutil_make_socket_nonblocking(listener);
return listener;
} while (0); int errno_save;
errno_save = errno;
evutil_closesocket(listener);
errno = errno_save; return -1;
}

最新文章

  1. JBOSS.71.1.Final安装配置
  2. C#如何反射出委托的签名,如何使用反射调用委托
  3. Eclipse中web项目部署至Tomcat【转】
  4. nginx(3、负载均衡)
  5. jquery mobile开发笔记之Ajax提交数据(转)
  6. DOM_节点层次_Document类型
  7. es6面试问题——Promise
  8. hdu 6093---Rikka with Number(计数)
  9. Hadoop就是一个别人造好的轮子
  10. ACM Wooden Stricks
  11. SQL小汇总
  12. vue-router基本使用
  13. (转)awesome-text-summarization
  14. Django 数据库操作进阶F和Q操作
  15. [1] 平面(Plane)图形的生成算法
  16. [CSS3] 3D桃心
  17. 解决Linux下pcieport 0000:00:1c.5问题导致的系统根目录/磁盘空间不足
  18. 主存储器与CPU的连接
  19. LintCode-5.第k大元素
  20. ZSTU OJ 4273 玩具

热门文章

  1. vue 中 限制 input 输入数字、小数位数等
  2. np.multiply
  3. 吴裕雄 python 神经网络——TensorFlow ckpt文件保存方法
  4. techiediaries网站的Laravel 6系列教程
  5. 通过aptitude降级包解决依赖问题(E:无法修正错误,因为您要求某些软件包保持现状)
  6. 我的B站主页:https://space.bilibili.com/611212 内有视频题解
  7. javascript 变量、常量 、 函数 声明
  8. cmd常用小命令
  9. 简单优化MySQL(后续在补充)
  10. springMVC的 Converter转换器 和 Formatter