evpp网络库代码分析(一)

旧巷老猫 提交于 2020-08-18 07:15:05

        evpp是奇虎360内部使用的开源多线程网络库,集tcp/udp/http多种协议的服务器和客户端支持。github代码路径是:https://github.com/Qihoo360/evpp,可以不依赖boost库,使用现代c++14语言(evpp/invoke_timer.cc的lambda表达式使用到了c++14的特性)进行编码。本项目高度参考了muduo网络库,而底层使用现成的libevent库作为事件驱动库,典型的一个reactor网络编程模式的例子,本文就是通过分析evpp源码来达到学习c++网络编程的效果。

        muduo代码我也拜读过,muduo有个特点,它完全是为linux而写的(譬如里面用到了eventfd,timerfd以及epoll等,都是linux系统特有的,而且还跟linux版本有关,系统版本太低也不支持,譬如eventfd),而evpp做了一定的平台兼容性,能一定程度做到支持windows平台,得益于libevent库。另外,木铎有个base库,是重复造轮子了,其他还好,也是一个不可多得的多线程网络服务器编程demo,值得参考,而evpp没有像muduo那样重新实现一套基础库(如线程库、互斥锁、条件变量等),而是利用了c++14自带的std::thread、std::mutex等,相对通用很多,而且学习这些类库使用在其他项目也能用得着,毕竟是c++的标准类库。

        摘抄了github上的说明,大家可以点进去前文给出的github路径阅读Readme:

        我们先给出基础的TCP服务器和客户端的例子,http的话我就不讲解了。

TCP服务器端例子:

#include <evpp/tcp_server.h>
#include <evpp/buffer.h>
#include <evpp/tcp_conn.h>

int main(int argc, char* argv[]) {
    std::string addr = "0.0.0.0:9099";
    int thread_num = 4;
    evpp::EventLoop loop;
    evpp::TCPServer server(&loop, addr, "TCPEchoServer", thread_num);
    server.SetMessageCallback([](const evpp::TCPConnPtr& conn,
                                 evpp::Buffer* msg) {
        LOG_INFO << "SetMessageCallback string: " << msg->ToString() << LOG_LR;
        conn->Send(msg);
    });
    server.SetConnectionCallback([](const evpp::TCPConnPtr& conn) {
        if (conn->IsConnected()) {
            LOG_INFO << "A new connection from " << conn->remote_addr() << LOG_LR;
        } else {
            LOG_INFO << "Lost the connection from " << conn->remote_addr() << LOG_LR;
        }
    });
    server.Init();
    server.Start();
    loop.Run();
    return 0;
}

而TCP客户端例子:

#include <evpp/tcp_client.h>
#include <evpp/buffer.h>
#include <evpp/tcp_conn.h>

int main(int argc, char* argv[]) {
    std::string addr = "127.0.0.1:9099";

    if (argc == 2) {
        addr = argv[1];
    }

    evpp::EventLoop loop;
    evpp::TCPClient client(&loop, addr, "TCPPingPongClient");
    client.SetMessageCallback([&loop, &client](const evpp::TCPConnPtr& conn,
                               evpp::Buffer* msg) {
        LOG_TRACE << "Receive a message [" << msg->ToString() << "]" << LOG_LR;
        client.Disconnect();
    });

    client.SetConnectionCallback([](const evpp::TCPConnPtr& conn) {
        if (conn->IsConnected()) {
            LOG_INFO << "Connected to " << conn->remote_addr() << LOG_LR;
            conn->Send("hello");
        } else {
            conn->loop()->Stop();
        }
    });
    client.Connect();
    loop.Run();
    return 0;
}

        看得出来类的使用跟muduo如出一辙,也是抛弃c++的继承,积极使用"std::function+std::bind"两兄弟。作者也是致敬了一番muduo库。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!