360 evpp现代化C++11高性能TCP UDP HTTP网络库

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1

安装方法,源码包有说明:https://github.com/Qihoo360/evpp

----------------------------------------------------------------------------------------------------------------

2

tcp回声服务器(官方示例)

#include 
#include 
#include 

#ifdef _WIN32
#include "../../winmain-inl.h"
#endif

void OnMessage(const evpp::TCPConnPtr& conn,
               evpp::Buffer* msg) {
    std::string s = msg->NextAllString();
    LOG_INFO << "Received a message [" << s << "]";
    conn->Send(s);

    if (s == "quit" || s == "exit") {
        conn->Close();
    }
}


void OnConnection(const evpp::TCPConnPtr& conn) {
    if (conn->IsConnected()) {
        LOG_INFO << "Accept a new connection from " << conn->remote_addr();
    } else {
        LOG_INFO << "Disconnected from " << conn->remote_addr();
    }
}


int main(int argc, char* argv[]) {
    std::string port = "9099";
    if (argc == 2) {
        port = argv[1];
    }
    std::string addr = std::string("0.0.0.0:") + port;
    evpp::EventLoop loop;
    evpp::TCPServer server(&loop, addr, "TCPEcho", 0);
    server.SetMessageCallback(&OnMessage);
    server.SetConnectionCallback(&OnConnection);
    server.Init();
    server.Start();
    loop.Run();
    return 0;
}

----------------------------------------------------------------------------------------------------------------

3

evpp::TCPServer类(主要)

#include

#pragma once

#include "evpp/inner_pre.h"
#include "evpp/event_loop.h"
#include "evpp/event_loop_thread_pool.h"
#include "evpp/tcp_callbacks.h"

#include "evpp/thread_dispatch_policy.h"
#include "evpp/server_status.h"

#include 

namespace evpp {

class Listener;

// We can use this class to create a TCP server.
// The typical usage is :
//      1. Create a TCPServer object
//      2. Set the message callback and connection callback
//      3. Call TCPServer::Init()
//      4. Call TCPServer::Start()
//      5. Process TCP client connections and messages in callbacks
//      6. At last call Server::Stop() to stop the whole server
//
// The examples code is as bellow:
// 
//     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) {
//         // Do something with the received message
//         conn->Send(msg); // At here, we just send the received message back.
//     });
//     server.SetConnectionCallback([](const evpp::TCPConnPtr& conn) {
//         if (conn->IsConnected()) {
//             LOG_INFO << "A new connection from " << conn->remote_addr();
//         } else {
//             LOG_INFO << "Lost the connection from " << conn->remote_addr();
//         }
//     });
//     server.Init();
//     server.Start();
//     loop.Run();
// 
//
class EVPP_EXPORT TCPServer : public ThreadDispatchPolicy, public ServerStatus {
public:
    typedef std::function DoneCallback;

    // @brief The constructor of a TCPServer.
    // @param loop -
    // @param listen_addr - The listening address with "ip:port" format
    // @param name - The name of this object
    // @param thread_num - The working thread count
    TCPServer(EventLoop* loop,
              const std::string& listen_addr/*ip:port*/,
              const std::string& name,
              uint32_t thread_num);
    ~TCPServer();

    // @brief Do the initialization works here.
    //  It will create a nonblocking TCP socket, and bind with the give address
    //  then listen on it. If there is anything wrong it will return false.
    // @return bool - True if anything goes well
    bool Init();

    // @brief Start the TCP server and we can accept new connections now.
    // @return bool - True if anything goes well
    bool Start();

    // @brief Stop the TCP server
    // @param cb - the callback cb will be invoked when
    //  the TCP server is totally stopped
    void Stop(DoneCallback cb = DoneCallback());

    // @brief Reinitialize some data fields after a fork
    void AfterFork();

public:
    // Set a connection event relative callback when the TCPServer
    // receives a new connection or an exist connection breaks down.
    // When these two events happened, the value of the parameter in the callback is:
    //      1. Received a new connection : TCPConn::IsConnected() == true
    //      2. An exist connection broken down : TCPConn::IsDisconnecting() == true
    void SetConnectionCallback(const ConnectionCallback& cb) {
        conn_fn_ = cb;
    }

    // Set the message callback to handle the messages from remote client
    void SetMessageCallback(MessageCallback cb) {
        msg_fn_ = cb;
    }

public:
    const std::string& listen_addr() const {
        return listen_addr_;
    }
private:
    void StopThreadPool();
    void StopInLoop(DoneCallback on_stopped_cb);
    void RemoveConnection(const TCPConnPtr& conn);
    void HandleNewConn(evpp_socket_t sockfd, const std::string& remote_addr/*ip:port*/, const struct sockaddr_in* raddr);
    EventLoop* GetNextLoop(const struct sockaddr_in* raddr);
private:
    EventLoop* loop_;  // the listening loop
    const std::string listen_addr_; // ip:port
    const std::string name_;
    std::unique_ptr listener_;
    std::shared_ptr tpool_;
    ConnectionCallback conn_fn_;
    MessageCallback msg_fn_;

    DoneCallback stopped_cb_;

    // always in the listening loop thread
    uint64_t next_conn_id_ = 0;
    typedef std::map ConnectionMap;
    ConnectionMap connections_;
};
}

----------------------------------------------------------------------------------------------------------------

4

std::function回调类型
part3中的两个evpp::TCPServer类的成员函数(设置回调函数)
void SetConnectionCallback(const ConnectionCallback& cb)
void SetMessageCallback(MessageCallback cb)
其回调类型在源码 #include "evpp/tcp_callbacks.h"

#pragma once

#include "evpp/inner_pre.h"

namespace evpp {
class Buffer;
class TCPConn;

typedef std::shared_ptr TCPConnPtr;
typedef std::function TimerCallback;

// When a connection established, broken down, connecting failed, this callback will be called
// This is called from a work-thread this is not the listening thread probably
typedef std::function ConnectionCallback;


typedef std::function CloseCallback;
typedef std::function WriteCompleteCallback;
typedef std::function HighWaterMarkCallback;

typedef std::function MessageCallback;

namespace internal {
inline void DefaultConnectionCallback(const TCPConnPtr&) {}
inline void DefaultMessageCallback(const TCPConnPtr&, Buffer*) {}
}

}

----------------------------------------------------------------------------------------------------------------

5

evpp::EventLoop类

evpp::EventLoop类是IO事件的驱动内核。这个类是event_base类的包装器,但不仅仅是一个包装器。它通过简单的方式,运行IO事件驱动循环。一个线程一个循环。

在evpp::TCPServer对象设置完回调函数及调用Init()、Start()之后,必须执行IO事件线程Run(),如part2示例。

----------------------------------------------------------------------------------------------------------------

6

以上是evpp tcp网络库的大致用法。udp、http用法参照源码。

 

evpp语法采用C++11的特性,大量使用std::string,而不是char*独占天;使用std::stringstream,而不是sprintf;易读的Lambda,而不是函数指针等等。满满的C++11诚意。http库更是可以弥补C++开发http服务器效率低的问题。膜拜360大佬们!

转载于:https://my.oschina.net/feistel/blog/3001279

你可能感兴趣的:(360 evpp现代化C++11高性能TCP UDP HTTP网络库)