evpp網絡庫代碼分析(一)

        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庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章