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