diff --git a/test_buffer_client/first_libevent.vcxproj b/test_buffer_client/first_libevent.vcxproj new file mode 100644 index 0000000..3325add --- /dev/null +++ b/test_buffer_client/first_libevent.vcxproj @@ -0,0 +1,162 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {129BF326-BFEE-4F1C-920C-0C302BB84895} + Win32Proj + firstlibevent + 10.0.17763.0 + test_buffer_client + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + true + ..\..\include + + + Console + true + ..\..\lib + libevent.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/test_buffer_client/first_libevent.vcxproj.user b/test_buffer_client/first_libevent.vcxproj.user new file mode 100644 index 0000000..6e2aec7 --- /dev/null +++ b/test_buffer_client/first_libevent.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test_buffer_client/makefile b/test_buffer_client/makefile new file mode 100644 index 0000000..2a401bf --- /dev/null +++ b/test_buffer_client/makefile @@ -0,0 +1,2 @@ +test_buffer_client:test_buffer_client.cpp + g++ $^ -o $@ -levent \ No newline at end of file diff --git a/test_buffer_client/test_buffer_client.cpp b/test_buffer_client/test_buffer_client.cpp new file mode 100644 index 0000000..91dc6bd --- /dev/null +++ b/test_buffer_client/test_buffer_client.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include + + +#ifdef _WIN32 +#include +#else +#include +#include +#endif // !_WIN32 + +using namespace std; + +static string recvstr = ""; +static int recvCount = 0; +static int sendCount = 0; + +void read_cb(bufferevent * bev, void *arg) { + cout << "[R]" << endl; + + char data[1024] = { 0 }; + int len = bufferevent_read(bev, data, sizeof(data) - 1); + if (len <= 0)return; + recvstr += data; + recvCount += len; + + /* if(strstr(data,"quit")!= NULL){ + cout << "quit" << endl; + bufferevent_free(bev); // BEV_OPT_CLOSE_ON_FREE 设置了这个才会关闭 + } */ + //发送数据 写入到输出缓冲 + bufferevent_write(bev, "ok", 3); +} + +void write_cb(bufferevent * bev, void *arg) { + cout << "[W]" << endl; +} + +//错误 超时 连接断开会进入 +void event_cb(struct bufferevent *bev, short what, void *ctx) { + cout << "[CB]" << endl; + + //读取超时事件发生后,数据读取停止 + if (what & BEV_EVENT_TIMEOUT && what & BEV_EVENT_READING) { + char data[1024] = { 0 }; + int len = bufferevent_read(bev, data, sizeof(data) - 1); + if (len > 0) { + recvCount += len; + recvstr += data; + } + cout << "read timeout " << endl; + + //bufferevent_enable(bev,EV_READ); //可以重新设置 + bufferevent_free(bev); + cout << recvstr << endl; + cout << "recvCOunt" << recvCount << " sendCount" << sendCount << endl; + + } + else if (what & BEV_EVENT_ERROR) { + bufferevent_free(bev); + } + else { + cout << "other " << endl; + } +} + +void listen_cb(struct evconnlistener *ev, evutil_socket_t s, + struct sockaddr *insin, int socklen, void *arg) +{ + cout << "listen_cb" << endl; + + struct sockaddr_in *sin = (struct sockaddr_in *)&insin; + int port = ntohs(sin->sin_port); + + char ip[16] = { 0 }; + evutil_inet_ntop(AF_INET, &sin->sin_addr, ip, sizeof(ip) - 1); + cout << "client ip is " << ip << "port is " << port << endl; + + + event_base* base = (event_base*)arg; + //创建bufferevent上下文 BEV_OPT_CLOSE_ON_FREE清理bufferevent时关闭socket + bufferevent * bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE); + bufferevent_enable(bev, EV_READ | EV_WRITE); + + //设置水位 + //读取水位 + bufferevent_setwatermark(bev, EV_READ, + 10, //低水位0就是无限制 默认0 有10个数据才会回调函数被调用 + 10); //高水位0就是无限制 默认0 超过10的数据会拆分成多个10调用多次 + + bufferevent_setwatermark(bev, EV_WRITE, + 5, // 低水位0就是无限制 默认0 缓冲数据低于5 写入回调内调用 + 0); //暂时无效 + + timeval t1 = { 0,50000 }; + bufferevent_set_timeouts(bev, &t1, NULL); + bufferevent_setcb(bev, read_cb, write_cb, event_cb, base); +} + +void clinet_read_cb(bufferevent * bev, void *arg) { + cout << "[clinet R]" << endl; + char data[1024] = { 0 }; + int len = bufferevent_read(bev, data, sizeof(data) - 1); + if (len <= 0)return; + cout << "[" << data << "]" << endl; + /* if(strstr(data,"quit")!= NULL){ + cout << "quit" << endl; + bufferevent_free(bev); // BEV_OPT_CLOSE_ON_FREE 设置了这个才会关闭 + } */ + //发送数据 写入到输出缓冲 + //bufferevent_write(bev,"ok",3); +} + +void clinet_write_cb(bufferevent * bev, void *arg) { + cout << "[clinet W]" << endl; + //激活write + FILE *fp = (FILE *)arg; + char data[1024] = { 0 }; + int len = fread(data, 1, sizeof(data) - 1, fp); + if (len <= 0) { + // 读到文件结尾或者文件出错 + fclose(fp); + //立刻清理 可能会造成缓冲数据没有发送结束 !! 不能在这里做 + //bufferevent_free(bev); + bufferevent_disable(bev, EV_WRITE); + return; + } + sendCount += len; + bufferevent_write(bev, data, len); + +} + +//错误 超时 连接断开会进入 +void clinet_event_cb(struct bufferevent *bev, short what, void *ctx) { + cout << "[ clinet CB]" << endl; + + //读取超时事件发生后,数据读取停止 + if (what & BEV_EVENT_TIMEOUT && what & BEV_EVENT_READING) { + cout << "read timeout " << endl; + + //bufferevent_enable(bev,EV_READ); //可以重新设置 + bufferevent_free(bev); + return; + + } + else if (what & BEV_EVENT_ERROR) { + bufferevent_free(bev); + return; + } + + //服务端的关闭事件 + if (what & BEV_EVENT_EOF) { + cout << "BEV_EVENT_EOF" << endl; + bufferevent_free(bev); + } + + if (what & BEV_EVENT_CONNECTED) { + cout << "BEV_EVENT_CONNECTED " << endl; + bufferevent_trigger(bev, EV_WRITE, 0); //触发写事件 + } +} + +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(); + sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(5001); + + evconnlistener_new_bind(base, + listen_cb, + base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, + 10, + (sockaddr *)&sin, + sizeof(sin)); + + { //防止变量名重定义 + //调用客户端代码 + // -1 内部创建socket + bufferevent * bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); + sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(5001); + evutil_inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr.s_addr); + + FILE *fp = fopen("test_buffer_client.cpp", "rb"); + //设置回调函数 + bufferevent_setcb(bev, clinet_read_cb, clinet_write_cb, clinet_event_cb, fp); + bufferevent_enable(bev, EV_READ | EV_WRITE); + int ret = bufferevent_socket_connect(bev, (sockaddr*)&sin, sizeof(sin)); + if (ret == 0) { + cout << "connected" << endl; + } + } + //进入事件主循环 + event_base_dispatch(base); + event_base_free(base); + + return 0; +} \ No newline at end of file diff --git a/test_buffer_client/test_buffer_client.sln b/test_buffer_client/test_buffer_client.sln new file mode 100644 index 0000000..5111269 --- /dev/null +++ b/test_buffer_client/test_buffer_client.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1525 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "first_libevent", "first_libevent.vcxproj", "{129BF326-BFEE-4F1C-920C-0C302BB84895}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Debug|x64.ActiveCfg = Debug|x64 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Debug|x64.Build.0 = Debug|x64 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Debug|x86.ActiveCfg = Debug|Win32 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Debug|x86.Build.0 = Debug|Win32 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Release|x64.ActiveCfg = Release|x64 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Release|x64.Build.0 = Release|x64 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Release|x86.ActiveCfg = Release|Win32 + {129BF326-BFEE-4F1C-920C-0C302BB84895}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {191D7F93-7554-493B-92E1-BB302C5A8383} + EndGlobalSection +EndGlobal