基于libevent实现了一个简单的echoclient。之前在网上看到的都是echoserver。这里演示一下使用libevent进行客户端编程的基本步骤。
先看代码:
#include "stdafx.h"
#include "event2/event.h"
#include "event2/util.h"
#define ECHO_PORT 8888
#define ECHO_SERVER "127.0.0.1"
struct echo_context{
struct event_base *base;
struct event *event_write;
struct event *event_read;
const char * echo_contents;
int echo_contents_len;
int recved;
};
void write_cb(evutil_socket_t sock, short flags, void * args)
{
struct echo_context *ec = (struct echo_context *)args;
int ret = send(sock, ec->echo_contents, ec->echo_contents_len, 0);
printf("connected, write to echo server: %d\n", ret);
event_add(ec->event_read, 0);
}
void read_cb(evutil_socket_t sock, short flags, void * args)
{
struct echo_context *ec = (struct echo_context *)args;
char buf[128];
int ret = recv(sock, buf, 128, 0);
printf("read_cb, read %d bytes\n", ret);
if(ret > 0)
{
ec->recved += ret;
buf[ret] = 0;
printf("recv:%s\n", buf);
}
else if(ret == 0)
{
printf("read_cb connection closed\n");
event_base_loopexit(ec->base, NULL);
return;
}
if(ec->recved < ec->echo_contents_len)
{
event_add(ec->event_read, 0);
}
}
static evutil_socket_t make_tcp_socket()
{
int on = 1;
evutil_socket_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
evutil_make_socket_nonblocking(sock);
#ifdef WIN32
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, sizeof(on));
#else
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
#endif
return sock;
}
static void echo_client(struct event_base *base)
{
evutil_socket_t sock = make_tcp_socket();
struct sockaddr_in serverAddr;
struct event * ev_write = 0;
struct event * ev_read = 0;
struct timeval tv={10, 0};
struct echo_context *ec = (struct echo_context*)calloc(1, sizeof(struct echo_context));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(ECHO_PORT);
#ifdef WIN32
serverAddr.sin_addr.S_un.S_addr = inet_addr(ECHO_SERVER);
#else
serverAddr.sin_addr.s_addr = inet_addr(ECHO_SERVER);
#endif
memset(serverAddr.sin_zero, 0x00, 8);
connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
ev_write = event_new(base, sock, EV_WRITE, write_cb, (void*)ec);
ev_read = event_new(base, sock, EV_READ , read_cb, (void*)ec);
ec->event_write = ev_write;
ec->event_read = ev_read;
ec->base = base;
ec->echo_contents = strdup("echo client tneilc ohce\n");
ec->echo_contents_len = strlen(ec->echo_contents);
ec->recved = 0;
event_add(ev_write, &tv);
}
int _tmain(int argc, _TCHAR* argv[])
{
struct event_base * base = 0;
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void) WSAStartup(wVersionRequested, &wsaData);
#endif
base = event_base_new();
echo_client(base);
event_base_dispatch(base);
event_base_free(base);
return 0;
}
代码是在windows上实现的。
使用libevent进行客户端编程的基本步骤,在《libevent实现http client》中已经提过,基本如下:
- 初始化event_base(后续要运行事件循环)
- 创建socket,设置为异步,连接server
- 创建写读写事件,先将写事件加入事件循环
- 在写事件回调中向server端发送请求并将读事件加入事件循环
- 在读事件回调中处理数据,并根据数据是否读取完毕决定是否继续添加读事件
结合本文的示例代码,通过event_base_new()创建event_base,在初始化客户端socket(echo_client)之后,调用event_base_dispatch运行事件循环。
echo_client函数初始化了socket,设置为非阻塞模式,调用connect连接到echoserver,然后添加一个写事件到事件循环中。当连接成功后,会触发写事件。这里将write_cb作为写事件的回调,在调用event_new()时传入。
write_cb()写入一个字符串,然后添加一个读事件,在读事件中读取echoserver的回应。
基本的过程就是这样子了。这是个简单的例子,更复杂的例子,基本流程也是一样的。
分享到:
相关推荐
【最新】C++ 使用libEvent实现http的post, get功能,【最新】C++ 使用libEvent实现http的post, get功能
这是一个使用libevent实现的web服务器,客户端采用CInternetSession来实现的,是一个完整的可用的例子,项目采用cmake来管理。提供给大家参考,有问题可以邮件给buptxu@qq.com,多谢。
1.libevent库编译工具为vs2019 2.环境为qt5.15.2 3.设置本地的目录,开启线程即可实现http服务器文件下载。
linux下使用libevent实现断网重连的tcp客户端,自动检测tcp连接断开,断开后能自动重连;如果连不上服务器,则一直尝试连接服务器,直至连接成功。
1.基于libevent实现relay服务器。2.基于libevent实现relay客户端
1、 运用libevent库,实现客户端和服务器的模式 2、 客户端发送消息,服务器端显示客户端传送过来的信息
libevent, 在https中,一个 public的libevent存储库 0.构建和安装( 简要) Autoconf $./configure $ make $ make verify # (optional) $ sudo make install
linux下的线程池和libevent配合实现的高并发tcp服务器,tcp通讯采用分帧的方式发包,帧包含帧头和数据部分,使用libevent的bufferevent方式来实现的帧提取。还配套有一个C#写的客户端测试程序。
libevent 多线程 HTTP post服务器
全部C代码,linux下的线程池和libevent配合实现的高并发tcp服务器,tcp通讯采用分帧的方式发包,帧包含帧头和数据部分,使用libevent的bufferevent方式来实现的帧提取,可直接使用GCC来编译。还配套有一个C#写的...
evhttp-http-proxy 通过 libevent 实现的 HTTP 代理请注意,需要 libevent-streaming,即 libevent 的扩展。 您可以忽略“pcmm”相关代码。
VS2003使用libevent库实现的httpd范例工程
libevent在MFC上的实现, 花了1周的时间研究各种TCP模型, 包括LINUX和WINDOWS平台等, 包括C&C++, C#, JAVA, GOLANG, ERLANG等居于IOCP, SELECT, POLL, EPOLL, KQUEUE, BIO, NIO, AIO, 并发语言等实现的同步或异步...
Libevent 服务端 客户端 代码实现 实现大并发 -------
速度:libevent 尝试使用每个平台上最高速的非阻塞 IO 实现,并且不引入太多的额外开 销。 可扩展性:libevent 被设计为程序即使需要上万个活动套接字的时候也可以良好工作。 方便:无论何时,最自然的使用 ...
libevent参考手册(中文版),包含libevent的设计说明、原理描述,模块介绍和接口说明。
本文的背景基于:国内博客对于libevent大多介绍Linux实现,大多是C语言的实现,Windows平台下C++相对较少或者较旧。 本文针对libevent从服务端、客户端两个角度实现了封装类,真正做到,我们在使用封装类时候,只...
在linux下C语言通过libevent操作串口,通过libevent来实现回调读取串口数据。全部C代码,可直接编译和测试。
在ubuntu里面使用 libevent 实现,作为
socket程序,客户端 服务器,5种模型 select WSAAsyncSelect EventSelect select OVERLAPPED CompletionPort libevent 共9个程序,1个启动client工具,一个client程序,7个服务器程序,各不相同