C++11網絡編程


Handy是一個簡潔優雅的C++11網絡庫,適用於linux與Mac平台。十行代碼即可完成一個完整的網絡服務器。

下面是echo服務器的代碼:

#include <handy/handy.h> using namespace std; using namespace handy; int main(int argc, const char* argv[]) { EventBase bases; //事件分發器 Signal::signal(SIGINT, [&]{ bases.exit(); }); //注冊Ctrl+C的信號處理器--退出事件分發循環 TcpServer echo(&bases); //創建服務器 int r = echo.bind("", 99); //綁定端口 exitif(r, "bind failed %d %s", errno, strerror(errno)); echo.onConnRead([](const TcpConnPtr& con) { con->send(con->getInput()); // echo 讀取的數據 }); bases.loop(); //進入事件分發循環 }

其中EventBase是事件分發器,內部使用epoll/kqueue進行IO事件分發。

EventBase功能豐富,還包含了定時任務等功能。

 

網絡編程中全異步處理請求的難度較高,特別是涉及業務邏輯,涉及數據庫使用等情況。大家使用的最常見的模型是用異步處理IO,保證大的並發量,使用多線程處理業務請求,簡化業務邏輯的編寫。這種半同步半異步的編程模型我們簡稱為HSHA(half sync half async)。

Handy能夠支持HSHA,下面是一個完整的服務器例子:

#include <handy/handy.h>

using namespace std;
using namespace handy; 
int main(int argc, const char* argv[]) {
    EventBase base;
    HSHA hsha(&base, 4); //啟動4個線程進行同步處理
    int r = hsha.bind("", 99);
    exitif(r, "bind failed");
   //注冊Ctrl+C的信號處理
    Signal::signal(SIGINT, [&]{ base.exit(); hsha.exit(); signal(SIGINT, SIG_DFL);});
   // 消息處理函數
    hsha.onMsg(new LineCodec, [](const TcpConnPtr& con, const string& input){
        int ms = rand() % 1000;
        info("processing a msg");
        usleep(ms * 1000);
        return util::format("%s used %d ms", input.c_str(), ms);
    });
    base.loop();
}

其中onMsg注冊消息處理函數,onMsg的第一個參數為消息解碼器,該解碼器把tcp連接的輸入字節流解碼為一個個消息,對每個完整的消息調用onMsg傳入的第二個cb參數。

cb參數的原型為string cb (const TcpConnPtr& con, const string& input),用戶只需要編寫這個cb函數,處理輸入,返回處理結果即可。cb函數在線程池中調用,因此處理函數中的sleep等操作不會堵塞網絡IO。上述例子中,用戶可以使用telnet登陸到這個hsha例子服務器上,發送消息給服務器,服務器端的日志里可以發現輸出‘processing a msg’的線程並非IO線程。

如果用戶需要更加靈活的處理,可以返回空字符串表示未處理完,可以直接操作con這個連接。

Handy還具備更多的功能,如定時處理,清理空閑連接等等,詳情參見https://github.com/yedf/handy

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM