libevent2 简单服务器客户端实现
来源:互联网 发布:微信协议软件 编辑:程序博客网 时间:2024/05/08 20:43
libevent2 简单服务器客户端实现
基本功能,应该比较容易扩展
windows版本,我用的vc编译,linux去掉wsa相关内容,将sprintf_s替换成snprintf应该就可以了。
server.cpp
/* socket server*/#include <iostream>#include <signal.h>#define WIN32#include <event2/event.h>#include <event2/listener.h>#include <event2/bufferevent.h>#pragma comment(lib,"ws2_32.lib")#pragma comment(lib,"libevent_core.lib")#pragma comment(lib,"libevent_extras.lib")using std::cout;using std::cerr;using std::endl;void p_evconnlistener_cb(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *);void p_bufferevent_read_cb(bufferevent* pBufferEvent, void* pUserData);void p_bufferevent_write_cb(bufferevent* pBufferEvent, void* pUserData);void p_bufferevent_event_cb(bufferevent* pBufferEvent, short what, void* pUserData);void p_sigint_cb(evutil_socket_t fd, short what, void* pUserData);int main(){ cout << "server start" << endl; // windows网络初始化 WSAData wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); // 初始化eventbase event_base* pEventBase = event_base_new(); if (pEventBase == NULL) { cerr << "event_base fail" << endl; return 1; } // 定制监听地址端口 sockaddr_in server_addr; size_t server_addr_len = sizeof(sockaddr_in); memset(&server_addr, 0, server_addr_len); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(ADDR_ANY); server_addr.sin_port = htons(7777); // 代替bind&listen方法的方法…… evconnlistener* pEvConnListener = evconnlistener_new_bind(pEventBase, p_evconnlistener_cb, pEventBase, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1, (sockaddr*)&server_addr, server_addr_len); // 监听<C-c>中断信号 event* pSigintEvent = evsignal_new(pEventBase, SIGINT, p_sigint_cb, pEventBase); if ((!pSigintEvent) || (event_add(pSigintEvent, NULL) < 0)) { cerr << "sigint event fail." << endl; return 1; } // 循环处理消息 event_base_dispatch(pEventBase); // 清理 evconnlistener_free(pEvConnListener); event_free(pSigintEvent); event_base_free(pEventBase); // windows网络停止 WSACleanup(); cout << "server stop" << endl; return 0;}// 连接回调void p_evconnlistener_cb(evconnlistener* pEvConnListener, evutil_socket_t fd, sockaddr* addr, int socklen, void* userData){ event_base* pEventBase = (event_base*)userData; // 绑定连接的socket和bufferevent(这里的socket默认就是非阻塞的) bufferevent* pBufferEvent = bufferevent_socket_new(pEventBase, fd, BEV_OPT_CLOSE_ON_FREE); if (!pBufferEvent) { cerr << "bufferevent fail." << endl; event_base_loopbreak(pEventBase); return; } // 添加监听socket,设置回调 bufferevent_setcb(pBufferEvent, p_bufferevent_read_cb, p_bufferevent_write_cb, p_bufferevent_event_cb, NULL); // 设置处理(监听?)内容:读、写 bufferevent_enable(pBufferEvent, EV_READ | EV_WRITE);}// 数据读取回调void p_bufferevent_read_cb(bufferevent* pBufferEvent, void* pUserData){ // 读数据 char info[255]; size_t infoLen = bufferevent_read(pBufferEvent, info, sizeof(info)); if (infoLen < sizeof(info)) info[infoLen] = 0; cout << "recv info:" << info << endl; // 返回数据 char info_ret[255]; sprintf_s(info_ret, sizeof(info_ret), "server ret:%s", info); bufferevent_write(pBufferEvent, info_ret, strlen(info_ret));}// 写数据回调void p_bufferevent_write_cb(bufferevent* pBufferEvent, void* pUserData){ cout << "react client complete." << endl;}// 事件处理(出错、socket中断)void p_bufferevent_event_cb(bufferevent* pBufferEvent, short what, void* pUserData){ if (what & BEV_EVENT_READING) cout << "event_cb BEV_EVENT_READING." << endl; if (what & BEV_EVENT_WRITING) cout << "event_cb BEV_EVENT_WRITING." << endl; if (what & BEV_EVENT_EOF) cout << "event_cb BEV_EVENT_EOF." << endl; if (what & BEV_EVENT_ERROR) cout << "event_cb BEV_EVENT_ERROR." << endl; if (what & BEV_EVENT_TIMEOUT) cout << "event_cb BEV_EVENT_TIMEOUT." << endl; if (what & BEV_EVENT_CONNECTED) cout << "event_cb BEV_EVENT_CONNECTED." << endl; bufferevent_free(pBufferEvent);}// <C-c>中断信号处理void p_sigint_cb(evutil_socket_t fd, short what, void* pUserData){ event_base* pEventBase = (event_base*)pUserData; timeval delay = { 2, 0 }; cout << "stop service in 2 seconds." << endl; event_base_loopexit(pEventBase, &delay);}
client.cpp
/* libevent临时测试客户端*/#include <iostream>#include <WinSock2.h>#pragma comment(lib,"ws2_32.lib")using std::cout;using std::endl;int main(){ WSAData wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(7777); size_t addrLen = sizeof(addr); SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { cout << "create sock error." << WSAGetLastError() << endl; return 0; } if (connect(sock, (const sockaddr*)&addr, addrLen) == SOCKET_ERROR) { cout << "connect error." << WSAGetLastError() << endl; closesocket(sock); return 0; } char info[255]; for (int i = 0; i < 10; ++i) { sprintf_s(info, sizeof(info), "client msg:%d", i); send(sock, info, strlen(info), 0); memset(info, 0, sizeof(info)); int infoLen = recv(sock, info, sizeof(info), 0); if (infoLen == 0) { cout << "sock closed." << endl; closesocket(sock); sock = NULL; break; } else if (infoLen < 0) { cout << "recv error." << WSAGetLastError() << endl; closesocket(sock); sock = NULL; break; } else { cout << "recv info:" << info << endl; } } if (sock) { closesocket(sock); sock = NULL; } WSACleanup(); return 0;}
0 0
- libevent2 简单服务器客户端实现
- libevent2入门例-简单的服务器(也有简短客户端)
- 简单Socket实现客户端和服务器连接
- Socket 简单实现服务器和客户端
- C#服务器客户端通信简单实现
- TCP SOCKET服务器|客户端简单实现
- JAVA实现简单的客户端服务器模型
- 简单实现python socket 服务器客户端
- Java实现服务器和客户端简单通信
- 实现简单UDP服务器客户端模型
- TCP服务器、客户端的简单实现
- UDP服务器、客户端的简单实现
- Android开发简单登录服务器,客户端实现登录服务器
- UDP简单实现并发服务器和客户端简单通信
- 简单socket服务器客户端
- Android简单实现Socket通信,客户端连接服务器后,服务器向客户端发送文字数据
- 用Java实现一个简单的服务器与客户端程序
- python学习(1)--实现简单的服务器与客户端
- Apache shiro集群实现 (六)分布式集群系统下的高可用session解决方案---Session共享
- BaseAnimation是基于开源的APP,致力于收集各种动画效果(最新版本1.3)
- ios url 带中文的问题
- packet sniffer抓包软件使用体验
- Redundant Paths
- libevent2 简单服务器客户端实现
- JS ajax自动刷新 清空属性值
- Windows Azure
- servlet学习小结
- Xcode定义Preprocessor Macros,编译宏。
- Java APNS开源库apns4j-1.0.1发布
- 正则表达式初步了解(参考jb51)
- iOS调用系统相册、相机 显示中文标题
- iOS自定义键盘输入样式(设置成时间选择器等)