使用Win32控制台实现libevent通信
libevent版本:libevent-2.0.22-stable
服务端:
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h> #include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h> static const int PORT = 9995; static char g_szWriteMsg[256] = { 0 };
static char g_szReadMsg[256] = { 0 };
static int g_iCnt = 0; static void listener_cb(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_readcb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *); int main(int argc, char **argv)
{
struct event_base *base;
struct evconnlistener *listener;
struct event *signal_event; struct sockaddr_in sin; WSADATA wsa_data;
WSAStartup(MAKEWORD(2, 2), &wsa_data); base = event_base_new();
if (!base)
{
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
} memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);//固定一个端口号 //创建、绑定、监听socket
listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&sin,
sizeof(sin)); if (!listener)
{
fprintf(stderr, "Could not create a listener!\n");
return 1;
} event_base_dispatch(base); evconnlistener_free(listener);
//event_free(signal_event);
event_base_free(base); printf("done\n");
return 0;
} //有连接来时调用
static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *sa, int socklen, void *user_data)
{
struct event_base *base = (struct event_base*)user_data;
struct bufferevent *bev; //构造一个bufferevent
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
if (!bev)
{
fprintf(stderr, "Error constructing bufferevent!");
event_base_loopbreak(base);
return;
} //绑定读事件回调函数、写事件回调函数、错误事件回调函数
bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, NULL); bufferevent_enable(bev, EV_WRITE);
bufferevent_enable(bev, EV_READ); const char *szMsg = "hi client!";
bufferevent_write(bev, szMsg, strlen(szMsg));
} static void conn_writecb(struct bufferevent *bev, void *user_data)
{
//printf("touch conn_writecb\n"); // if ( strlen(g_szWriteMsg) > 0 )
// {
// bufferevent_write(bev, g_szWriteMsg, strlen(g_szWriteMsg));
// memset(g_szWriteMsg, 0x00, sizeof(g_szWriteMsg));
// }
} static void conn_readcb(struct bufferevent *bev, void *user_data)
{
//printf("touch conn_readcb\n");
memset(g_szReadMsg, 0x00, sizeof(g_szReadMsg));
struct evbuffer *input = bufferevent_get_input(bev);
size_t sz = evbuffer_get_length(input);
if (sz > 0)
{
bufferevent_read(bev, g_szReadMsg, sz);
printf("cli:>>%s\n", g_szReadMsg);
memset(g_szWriteMsg, 0x00, sizeof(g_szWriteMsg));
snprintf(g_szWriteMsg, sizeof(g_szWriteMsg) - 1, "hi client, this count is %d", g_iCnt);
g_iCnt++;
//printf("ser:>>");
//gets(g_szWriteMsg);
//scanf("%s", g_szWriteMsg); bufferevent_write(bev, g_szWriteMsg, strlen(g_szWriteMsg));
}
} static void conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
if (events & BEV_EVENT_EOF)
{
printf("Connection closed.\n");
}
else if (events & BEV_EVENT_ERROR)
{
printf("Got an error on the connection: %s\n", strerror(errno));/*XXX win32*/
}
/* None of the other events can happen here, since we haven't enabled
* timeouts */
bufferevent_free(bev);
}
客户端
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h> #include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h> static const int PORT = 9995;
static char g_szWriteMsg[256] = { 0 };
static char g_szReadMsg[256] = { 0 };
static int g_iCnt = 0;
static void conn_writecb(struct bufferevent *, void *);
static void conn_readcb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *); int main(int argc, char **argv)
{
struct event_base *base; struct sockaddr_in sin; WSADATA wsa_data;
WSAStartup(MAKEWORD(2, 2), &wsa_data); base = event_base_new();
if (!base)
{
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
} memset(&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT); struct bufferevent* bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
if (bev == NULL)
{
fprintf(stderr, "socket init failed\n");
return 1;
}
bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, NULL); //连接服务端
int flag = bufferevent_socket_connect(bev, (struct sockaddr*)&sin, sizeof(sin));
if (-1 == flag)
{
fprintf(stderr, "connect failed\n");
return 1;
}
bufferevent_enable(bev, EV_READ | EV_WRITE); event_base_dispatch(base);
event_base_free(base); printf("done\n");
return 0;
} static void conn_writecb(struct bufferevent *bev, void *user_data)
{
//printf("touch conn_writecb\n"); // if ( strlen(g_szWriteMsg) > 0 )
// {
// bufferevent_write(bev, g_szWriteMsg, strlen(g_szWriteMsg));
// memset(g_szWriteMsg, 0x00, sizeof(g_szWriteMsg));
// }
} static void conn_readcb(struct bufferevent *bev, void *user_data)
{
//printf("touch conn_readcb\n");
memset(g_szReadMsg, 0x00, sizeof(g_szReadMsg));
struct evbuffer *input = bufferevent_get_input(bev);
size_t sz = evbuffer_get_length(input);
if (sz > 0)
{
bufferevent_read(bev, g_szReadMsg, sz);
printf("ser:>>%s\n", g_szReadMsg);
memset(g_szWriteMsg, 0, sizeof(g_szWriteMsg));
snprintf(g_szWriteMsg, sizeof(g_szWriteMsg) - 1, "hi server,this count is %d", g_iCnt);
g_iCnt++;
//printf("cli:>>");
//gets(g_szWriteMsg);
//scanf("%s", g_szWriteMsg);
bufferevent_write(bev, g_szWriteMsg, strlen(g_szWriteMsg));
}
} static void conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
if (events & BEV_EVENT_EOF)
{
printf("Connection closed.\n");
}
else if (events & BEV_EVENT_ERROR)
{
printf("Got an error on the connection: %s\n",
strerror(errno));/*XXX win32*/
}
else if (events & BEV_EVENT_CONNECTED)
{
//连接成功时走这里,并且要客户端第一次触发读事件后连接才真正建立起来
printf("connect success\n");
const char* msg = "hi server,hao are you";
bufferevent_write(bev, msg, strlen(msg));
return;
}
bufferevent_free(bev);
}
参考链接:
https://www.imooc.com/article/292022
使用Win32控制台实现libevent通信的更多相关文章
- 【转】WIN32 控制台程序
http://blog.csdn.net/houmin0036/article/details/7702236 win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运行的应用 ...
- vc2010 win32 控制台应用程序中文乱码
vc2010 win32 控制台应用程序中文乱码 在 vc2010 上用 win32 控制台程序写些测试代码调用 windows api ,处理错误信息时,发现用 wprintf 输出的错误信息出现了 ...
- win32控制台实现按任意键退出的功能
win7之后的五win32 控制台出现了程序运行完之后就立即结束的问题,程序员根本无法看输出的结果.未来让控制台运行完之后能够等待程序员的操作.可以使用: system("PAUSE&quo ...
- C# Win32控制台应用程序忽略 Ctrl + C,阻止程序退出
C# Win32控制台应用程序忽略 Ctrl + C,阻止程序退出,这里使用到了Windows API SetConsoleCtrlHandler函数 注意:在VS中调试执行时,在处理程序例程中设置断 ...
- Linux终端和win32控制台文本颜色输出
在使用putty.secureCRT.XShell等终端仿真器连接linux系统时,ls.vim等工具的输出都含有各种颜色,这些颜色的输出大大地增强了文本的可读性. 通常我们可以使用echo命令加-e ...
- Visual Studio C++ Win32控制台应用程序,Win32项目,MFC的区别
背景 Visual Studio C++ 创建新项目蹦出来如下选项: Win32控制台应用程序,Win32项目,MFC有什么区别? 正文: Win32控制台,没有界面,命令行执行生成的文件则直接在后台 ...
- win32应用程序和win32控制台应用程序的区别
win32应用程序是有窗体的(当然也可以没有),有Windows消息循环机制的.而win32控制台应用程序只是在控制台下运行的程序,类似以前dos的程序. 后续答案: Win32 Appl ...
- Win32控制台程序和Win32应用程序
刚接触Windows那一套,大多数概念都还没建立起来,整理了一下网上对“Win32控制台程序”的理解,谢谢各位网友了. win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运 ...
- vs2008 新建win32控制台程序提示:脚本错误
解决方案: 1.根据错误信息中的url,找到对应文件夹下的htm文件 2.使用notepad++打开default.htm文件,找到错误提示的434行,注释掉433和434行 然后保存文件,重新新建w ...
- Win32控制台、Win32项目、MFC项目、CLR控制台、CLR空项目、空项目区别
转载:https://blog.csdn.net/zfmss/article/details/79244696 1.Win32控制台 初始代码模版以main为程序入口,默认情况下,只链接C++运行时库 ...
随机推荐
- vue总是报错:Trailing spaces not allowed
翻译: Trailing spaces not allowed:不允许尾随空格 1-报错: 2-解决: 你的某些行的空格多了,删掉就行了 以我的截图为例 代码12行出错 选中12行(点击前面的1 ...
- 在VS Code中vue引入新版vue-awesome-swiper编译时提示swiper/dist/css/swiper.css无法导入的问题
在安装vue-awesome-swiper时报错swiper/dist/css/swiper.min.css找不到,如下如: 有的回答安装6.0版本的话需要引入另外一个css import 'swip ...
- 探索自联接(SELF JOIN):揭示数据间复杂关系的强大工具
title: 探索自联接(SELF JOIN):揭示数据间复杂关系的强大工具 date: 2025/1/11 updated: 2025/1/11 author: cmdragon excerpt: ...
- Mac安装brew的四种方法(指定能行)
一,执行brew官网命令安装brew https://brew.sh/ 官网中复制下图中命令,在terminal中输入该命令,即: /bin/bash -c "$(curl -fsSL ht ...
- Collection的子接口之一:List 接口
List 接口概述: 鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组 List集合类中 元素有序.且可重复,集合中的每个元素都有其对应的顺序索引. List容器中的元素都对 ...
- 接口(interface):实例化时要覆盖所有抽象方法,否则仍为抽象类
概述 /* * 接口的使用 * 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能定义全局 ...
- Oracle数据快照设置
1.1 手册目的 该手册主要目的是用于生产环境排查问题及恢复用户误操作删除数据及程序错误导致数据丢失使用. 1.2 查看Undo表空间参数 在命令窗口查询Undo表空间的快照参数 1 show par ...
- “天翼云息壤杯”高校AI大赛福建赛区启动!
11月20日,2024首届全国"天翼云息壤杯"高校AI 大赛(福建赛区)正式启动.中国电信福建公司携手华为公司.福建省计算机学会.福建省自动化学会,正式启动天翼云科技有限公司承办的 ...
- RocketMQ实战—5.消息重复+乱序+延迟的处理
大纲 1.根据RocketMQ原理分析为什么会重复发优惠券 2.引入幂等性机制来保证数据不会重复 3.如何用死信队列处理优惠券系统数据库宕机 4.基于RocketMQ的订单库同步为什么会消息乱序 5. ...
- C#正则提取字符串中的数字
首先需要引入命名空间System.Text.RegularExpressions,具体实现如下所示: //提取纯数字,该方式会将所有数字提取出来并拼接在一起,如:"ABC#123@AS456 ...