`
king_tt
  • 浏览: 2232987 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

libevent实现echoclient

 
阅读更多

基于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》中已经提过,基本如下:

  1. 初始化event_base(后续要运行事件循环)
  2. 创建socket,设置为异步,连接server
  3. 创建写读写事件,先将写事件加入事件循环
  4. 在写事件回调中向server端发送请求并将读事件加入事件循环
  5. 在读事件回调中处理数据,并根据数据是否读取完毕决定是否继续添加读事件
结合本文的示例代码,通过event_base_new()创建event_base,在初始化客户端socket(echo_client)之后,调用event_base_dispatch运行事件循环。

echo_client函数初始化了socket,设置为非阻塞模式,调用connect连接到echoserver,然后添加一个写事件到事件循环中。当连接成功后,会触发写事件。这里将write_cb作为写事件的回调,在调用event_new()时传入。

write_cb()写入一个字符串,然后添加一个读事件,在读事件中读取echoserver的回应。

基本的过程就是这样子了。这是个简单的例子,更复杂的例子,基本流程也是一样的。


分享到:
评论

相关推荐

    libevent实现http服务器实现文件下载功能

    在这个场景下,我们可以使用libevent库来实现高效、轻量级的事件驱动网络编程。libevent是一个跨平台的库,用于处理大量并发连接,尤其适用于服务器端应用。在本案例中,我们将探讨如何使用libevent在VS2019环境下,...

    libevent web服务器实现

    这是一个使用libevent实现的web服务器,客户端采用CInternetSession来实现的,是一个完整的可用的例子,项目采用cmake来管理。提供给大家参考,有问题可以邮件给buptxu@qq.com,多谢。

    【最新】C++ 使用libEvent实现http的post, get功能

    本篇将深入探讨如何利用libEvent库在C++中实现HTTP的POST和GET请求。 首先,理解HTTP的基本概念至关重要。HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于客户端和服务器之间的通信。GET和POST是...

    libevent实现UDP relay服务器与客户端

    本篇文章将深入探讨如何利用libevent来实现UDP(User Datagram Protocol)的relay服务器和客户端。 首先,我们需要理解UDP协议的基本特性。UDP是一种无连接的传输层协议,它不保证数据包的顺序、可靠性和错误校验。...

    linux下使用libevent实现断网重连的tcp客户端

    linux下使用libevent实现断网重连的tcp客户端,自动检测tcp连接断开,断开后能自动重连;如果连不上服务器,则一直尝试连接服务器,直至连接成功。

    运用libevent库实现客户服务器模式

    本篇文章将详细探讨如何运用`libevent`库来实现客户端与服务器间的通信,以及在实际操作中如何编写TCP客户端和服务器。 首先,`libevent`库的核心功能是它提供了一种高效的事件模型,允许程序在等待I/O事件(如网络...

    libevent和线程池配合实现的高并发tcp服务器

    全部C代码,linux下的线程池和libevent配合实现的高并发tcp服务器,tcp通讯采用分帧的方式发包,帧包含帧头和数据部分,使用libevent的bufferevent方式来实现的帧提取,可直接使用GCC来编译。还配套有一个C#写的...

    libevent 多线程 HTTP post服务器

    描述中提到的“libevent 多线程 HTTP post服务器”表明这是一个利用libevent库开发的服务端程序,该程序能够接收并处理来自客户端的HTTP POST请求,并且采用了多线程技术以实现并发处理,提升系统性能。这通常意味着...

    libevent, 在https中,一个 public的libevent存储库.zip

    libevent, 在https中,一个 public的libevent存储库 0.构建和安装( 简要) Autoconf $./configure $ make $ make verify # (optional) $ sudo make install

    线程池和libevent配合实现的高并发tcp服务器 (不要下载,有缺陷,不能删除)

    linux下的线程池和libevent配合实现的高并发tcp服务器,tcp通讯采用分帧的方式发包,帧包含帧头和数据部分,使用libevent的bufferevent方式来实现的帧提取。还配套有一个C#写的客户端测试程序。

    基于libevent的视频服务器源代码

    【基于libevent的视频服务器源代码】是一种使用libevent库实现的视频服务器程序,它能够处理实时视频数据的传输,并具备基本的流媒体转发功能。libevent是一个事件通知库,适用于编写高性能、高并发的网络服务,尤其...

    Libevent 服务端 客户端 代码实现

    在本文中,我们将深入探讨Libevent如何实现服务端和客户端的代码,并理解其在网络编程中的核心概念。 首先,我们要了解Libevent的核心概念——事件模型。在计算机编程中,事件驱动编程是一种设计模式,其中程序的...

    libevent的视频服务器源代码

    1. **连接管理**:Libevent的事件机制可以很好地处理客户端的连接请求,通过监听套接字上的读写事件,实现新连接的接入和数据的接收。 2. **视频流处理**:服务器需要识别并解析视频流格式,如RTMP、HLS、DASH等,...

    VS2003使用libevent库实现的httpd范例工程

    "VS2003使用libevent库实现的httpd范例工程" 指的是一个使用Visual Studio 2003(VS2003)开发的项目,该项目集成并应用了libevent库来构建一个简单的HTTP服务器。libevent是一个开源的事件通知库,它允许程序员在多...

    evhttp-http-proxy:通过 libevent 实现的 HTTP 代理

    evhttp-http-proxy 通过 libevent 实现的 HTTP 代理请注意,需要 libevent-streaming,即 libevent 的扩展。 您可以忽略“pcmm”相关代码。

    libevent参考手册中文版_libevent-2.1.5.pdf

    libevent是一个高性能的事件通知库,主要由Nick Mathewson和Abdul Razzaq开发,用C语言编写。它基于Reactor设计模式,并提供了一个轻量级、跨平台、多线程的事件循环,广泛应用于网络服务器的开发中,能够处理多种I/...

    libevent在MFC上的实现(工具:LibeventServer.exe)

    libevent在MFC上的实现, 花了1周的时间研究各种TCP模型, 包括LINUX和WINDOWS平台等, 包括C&C++, C#, JAVA, GOLANG, ERLANG等居于IOCP, SELECT, POLL, EPOLL, KQUEUE, BIO, NIO, AIO, 并发语言等实现的同步或异步...

    libevent多线程处理

    本文将深入探讨如何在多线程环境中使用Libevent进行事件处理,并分享一个基于Libevent的多线程实现案例。 首先,理解Libevent的核心机制至关重要。Libevent提供了一个事件基础结构,它能够将来自不同来源的事件(如...

    VS2015编译后的libevent头文件和库文件——基于libevent-2.1.10

    libevent是一个开源的事件通知库,它在C语言中实现,广泛应用于网络编程,尤其是服务器端的高并发处理。它通过提供一个统一的API,使得开发者能够方便地处理各种I/O事件,如网络套接字、信号、定时器等。在本资源中...

    libevent-vs2017编译

    标题"libevent-vs2017编译"指的是使用Visual Studio 2017在Windows环境下编译开源库Libevent。Libevent是一个事件通知库,广泛用于编写高性能网络服务器,它提供了异步事件处理的能力,允许程序高效地处理大量并发...

Global site tag (gtag.js) - Google Analytics