女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>基于asio的網絡通信框架asio2

基于asio的網絡通信框架asio2

2022-06-22 | zip | 20.50 MB | 次下載 | 2積分

資料介紹

授權協議 GPL
開發語言 C/C++
操作系統 跨平臺
軟件類型 開源軟件
所屬分類 程序開發高性能網絡開發庫

軟件簡介

?

開源基于asio的網絡通信框架asio2,支持TCP,UDP,HTTP,RPC,SSL,跨平臺,支持可靠UDP,支持TCP自動拆包,TCP數據報模式等?

C++開發網絡通信程序時用asio是個不錯的選擇,但asio本身是一套函數集,自己還要處理諸如“通信線程池管理、連接及生命周期管理、多線程收發數據的同步保護等”。因此這里對asio進行了一層封裝,大大簡化了對asio的使用。代碼使用了C++17相關功能,所以只能用在C++17以上。

其中http和websocket部分用的是boost::beast,因此如果需要用到http或websocket的功能,則必須使用boost庫,如果用不到http則直接使用獨立的asio即可。在config.hpp中通過對ASIO_STANDALONE這個宏定義的開關,即可設置是使用boost::asio還是使用asio standalone.

代碼大量使用了CRTP模板編程實現(沒有使用virtual而用CRTP實現的靜態多態),因此編譯比較耗時,但執行效率相對較好一點。


github地址https://github.com/zhllxt/asio2

碼云地址https://gitee.com/zhllxt/asio2

A open source cross-platform c++ library for network programming based on asio,support for tcp,udp,http,rpc,ssl and so on.

  • 支持TCP,UDP,HTTP,WEBSOCKET,RPC,ICMP,SERIAL_PORT等;
  • 支持可靠UDP(基于KCP),支持SSL,支持從內存字符串加載SSL證書;
  • TCP支持數據拆包功能(按指定的分隔符對數據自動進行拆包,保證用戶收到的數據是一個完整的數據包);實現了TCP的數據報模式(類似WEBSOCKET);
  • 支持windows,linux,32位,64位;
  • 依賴asio(boost::asio或獨立asio均可,若需要HTTP功能必須使用boost::asio),依賴C++17;
  • 代碼采用hpp頭文件方式,以源碼級鏈入,無需編譯,只需在工程的Include包含目錄中添加asio2路徑,然后在源碼中#include 包含頭文件即可;
  • demo目錄包含大量的示例工程(工程基于VS2017創建),各種使用方法請參考示例代碼;

TCP:

服務端:

asio2::tcp_server server;
server.bind_recv([&server](std::shared_ptr & session_ptr, std::string_view s)
{
????session_ptr->no_delay(true);
????printf("recv : %u %.*s\n", (unsigned)s.size(), (int)s.size(), s.data());
????// 異步發送(所有發送操作都是異步且線程安全的)
    session_ptr->send(s);
    // 發送時指定一個回調函數,當發送完成后會調用此回調函數,bytes_sent表示實際發送的字節數,
    // 發送是否有錯誤可以用asio2::get_last_error()函數來獲取錯誤碼
    // session_ptr->send(s, [](std::size_t bytes_sent) {});
}).bind_connect([&server](auto & session_ptr)
{
????printf("client enter : %s %u %s %u\n",
????session_ptr->remote_address().c_str(), session_ptr->remote_port(),
????????session_ptr->local_address().c_str(), session_ptr->local_port());
????// 可以用session_ptr這個會話啟動一個定時器,這個定時器是在這個session_ptr會話的數據收
????// 發線程中執行的,這對于連接狀態的判斷或其它需求很有用(尤其在UDP這種無連接的協議中,有
????// 時需要在數據處理過程中使用一個定時器來延時做某些操作,而且這個定時器還需要和數據處理
????// 在同一個線程中安全觸發)
????//session_ptr->start_timer(1, std::chrono::seconds(1), []() {});
}).bind_disconnect([&server](auto & session_ptr)
{
	printf("client leave : %s %u %s\n",
		session_ptr->remote_address().c_str(),
		session_ptr->remote_port(), asio2::last_error_msg().c_str());
});
server.start("0.0.0.0", "8080");
//server.start("0.0.0.0", "8080", '\n'); // 按\n自動拆包(可以指定任意字符)
//server.start("0.0.0.0", "8080", "\r\n"); // 按\r\n自動拆包(可以指定任意字符串)
//server.start("0.0.0.0", "8080", match_role('#')); // 按match_role指定的規則自動拆包(match_role請參考demo代碼)(用于對用戶自定義的協議拆包)
//server.start("0.0.0.0", "8080", asio::transfer_exactly(100)); // 每次接收固定的100字節
//server.start("0.0.0.0", "8080", asio2::use_dgram); // 數據報模式的TCP,無論發送多長的數據,雙方接收的一定是相應長度的整包數據

客戶端:

asio2::tcp_client client;
client.bind_connect([&](asio::error_code ec)
{
	if (asio2::get_last_error())
		printf("connect failure : %d %s\n", asio2::last_error_val(), asio2::last_error_msg().c_str());
	else
		printf("connect success : %s %u\n", client.local_address().c_str(), client.local_port());

	client.send("");
}).bind_disconnect([](asio::error_code ec)
{
	printf("disconnect : %d %s\n", asio2::last_error_val(), asio2::last_error_msg().c_str());
}).bind_recv([&](std::string_view sv)
{
	printf("recv : %u %.*s\n", (unsigned)sv.size(), (int)sv.size(), sv.data());

	client.send(sv);
})
	//.bind_recv(on_recv) // 綁定全局函數
	//.bind_recv(std::bind(&listener::on_recv, &lis, std::placeholders::_1)) // 綁定成員函數(具體請查看demo代碼)
	//.bind_recv(&listener::on_recv, lis) // 按lis對象的引用來綁定成員函數(具體請查看demo代碼)
	//.bind_recv(&listener::on_recv, &lis) // 按lis對象的指針來綁定成員函數(具體請查看demo代碼)
	;
client.async_start("0.0.0.0", "8080"); // 異步連接服務端
//client.start("0.0.0.0", "8080"); // 同步連接服務端
//client.async_start("0.0.0.0", "8080", '\n'); // 按\n自動拆包(可以指定任意字符)
//client.async_start("0.0.0.0", "8080", "\r\n"); // 按\r\n自動拆包(可以指定任意字符串)
//client.async_start("0.0.0.0", "8080", match_role); // 按match_role指定的規則自動拆包(match_role請參考demo代碼)(用于對用戶自定義的協議拆包)
//client.async_start("0.0.0.0", "8080", asio::transfer_exactly(100)); // 每次接收固定的100字節
//client.start("0.0.0.0", "8080", asio2::use_dgram); // 數據報模式的TCP,無論發送多長的數據,雙方接收的一定是相應長度的整包數據
// 發送時也可以指定use_future參數,然后通過返回值future來阻塞等待直到發送完成,發送結果的錯誤碼和發送字節數
// 保存在返回值future中(注意,不能在通信線程中用future去等待,這會阻塞通信線程進而導致死鎖)
// std::future> future = client.send("abc", asio::use_future); 

UDP:

服務端:

asio2::udp_server server;
// ... 綁定監聽器(請查看demo代碼)
server.start("0.0.0.0", "8080"); // 常規UDP
//server.start("0.0.0.0", "8080", asio2::use_kcp); // 可靠UDP

客戶端:

asio2::udp_client client;
// ... 綁定監聽器(請查看demo代碼)
client.start("0.0.0.0", "8080");
//client.async_start("0.0.0.0", "8080", asio2::use_kcp); // 可靠UDP

RPC:

服務端:

asio2::rpc_server server;
// ... 綁定監聽器(請查看demo代碼)
A a; // A的定義請查看demo代碼
server.bind("add", add); // 綁定RPC全局函數
server.bind("mul", &A::mul, a); // 綁定RPC成員函數
server.bind("cat", [&](const std::string& a, const std::string& b) { return a + b; }); // 綁定lambda表達式
server.bind("get_user", &A::get_user, a); // 綁定成員函數(按引用)
server.bind("del_user", &A::del_user, &a); // 綁定成員函數(按指針)
//server.start("0.0.0.0", "8080", asio2::use_dgram); // 使用TCP數據報模式作為RPC通信底層支撐,啟動服務端時必須要使用use_dgram參數
server.start("0.0.0.0", "8080"); // 使用websocket作為RPC通信底層支撐(需要到rcp_server.hpp文件末尾代碼中選擇使用websocket)

客戶端:

asio2::rpc_client client;
// ... 綁定監聽器(請查看demo代碼)
//client.start("0.0.0.0", "8080", asio2::use_dgram); // 使用TCP數據報模式作為RPC通信底層支撐,啟動服務端時必須要使用use_dgram參數
client.start("0.0.0.0", "8080"); // 使用websocket作為RPC通信底層支撐
asio::error_code ec;
// 同步調用RPC函數
int sum = client.call(ec, std::chrono::seconds(3), "add", 11, 2);
printf("sum : %d err : %d %s\n", sum, ec.value(), ec.message().c_str());
// 異步調用RPC函數,第一個參數是回調函數,當調用完成或超時會自動調用該回調函數,如果超時或其它錯誤,
// 錯誤碼保存在ec中,這里async_call沒有指定返回值類型,則lambda表達式的第二個參數必須要指定類型
client.async_call([](asio::error_code ec, int v)
{
	printf("sum : %d err : %d %s\n", v, ec.value(), ec.message().c_str());
}, "add", 10, 20);
// 這里async_call指定了返回值類型,則lambda表達式的第二個參數可以為auto類型
client.async_call([](asio::error_code ec, auto v)
{
	printf("sum : %d err : %d %s\n", v, ec.value(), ec.message().c_str());
}, "add", 12, 21);
// 返回值為用戶自定義數據類型(user類型的定義請查看demo代碼)
user u = client.call(ec, "get_user");
printf("%s %d ", u.name.c_str(), u.age);
for (auto &[k, v] : u.purview)
{
	printf("%d %s ", k, v.c_str());
}
printf("\n");

u.name = "hanmeimei";
u.age = ((int)time(nullptr)) % 100;
u.purview = { {10,"get"},{20,"set"} };
// 如果RPC函數的返回值為void,則用戶回調函數只有一個參數即可
client.async_call([](asio::error_code ec)
{
}, "del_user", std::move(u));

HTTP:

服務端:

asio2::http_server server;
server.bind_recv([&](std::shared_ptr & session_ptr, http::request& req)
{
    // 在收到http請求時嘗試發送一個文件到對端
    {
        // 如果請求是非法的,直接發送錯誤信息到對端并返回
        if (req.target().empty() ||
        req.target()[0] != '/' ||
        req.target().find("..") != beast::string_view::npos)
        {
            session_ptr->send(http::make_response(http::status::bad_request, "Illegal request-target"));
            session_ptr->stop(); // 同時直接斷開這個連接
            return;
        }

        // Build the path to the requested file
        std::string path(req.target().data(), req.target().size());
        path.insert(0, std::filesystem::current_path().string());
        if (req.target().back() == '/')
            path.append("index.html");

        // 打開文件
        beast::error_code ec;
        http::file_body::value_type body;
        body.open(path.c_str(), beast::file_mode::scan, ec);

        // 如果打開文件失敗,直接發送錯誤信息到對端并直接返回
        if (ec == beast::errc::no_such_file_or_directory)
        {
            session_ptr->send(http::make_response(http::status::not_found,
            std::string_view{ req.target().data(), req.target().size() }));
            return;
        }

        // Cache the size since we need it after the move
        auto const size = body.size();

        // 生成一個文件形式的http響應對象,然后發送給對端
        http::response res{
        std::piecewise_construct,
        std::make_tuple(std::move(body)),
        std::make_tuple(http::status::ok, req.version()) };
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, http::extension_to_mimetype(path));
        res.content_length(size);
        res.keep_alive(req.keep_alive()); 
        res.chunked(true);
        // Specify a callback function when sending
        //session_ptr->send(std::move(res));
        session_ptr->send(std::move(res), [&res](std::size_t bytes_sent)
        {
            auto opened = res.body().is_open(); std::ignore = opened;
            auto err = asio2::get_last_error(); std::ignore = err;
        });
        //session_ptr->send(std::move(res), asio::use_future);
        return;
    }

    std::cout << req << std::endl;
    if (true)
    {
        // 用make_response生成一個http響應對象,狀態碼200表示操作成功,"suceess"是HTTP消息的body部分內容
        auto rep = http::make_response(200, "suceess");
        session_ptr->send(rep, []()
        {
            auto err = asio2::get_last_error(); std::ignore = err;
        });
    }
    else
    {
        // 也可以直接發送一個http標準響應字符串,內部會將這個字符串自動轉換為http響應對象再發送出去
        std::string_view rep =
            "HTTP/1.1 404 Not Found\r\n"\
            "Server: Boost.Beast/181\r\n"\
            "Content-Length: 7\r\n"\
            "\r\n"\
            "failure";
        // test send string sequence, the string will automatically parsed into a standard http request
        session_ptr->send(rep, [](std::size_t bytes_sent)
        {
            auto err = asio2::get_last_error(); std::ignore = err;
        });
    }
});
server.start(host, port);

客戶端:

asio2::error_code ec;
auto req1 = http::make_request("http://www.baidu.com/get_user?name=a"); // 通過URL字符串生成一個http請求對象
auto req2 = http::make_request("GET / HTTP/1.1\r\nHost: 127.0.0.1:8443\r\n\r\n"); // 通過http協議字符串生成一個http請求對象
req2.set(http::field::timeout, 5000); // 給請求設置一個超時時間
auto rep1 = asio2::http_client::execute("http://www.baidu.com/get_user?name=a", ec); // 通過URL字符串直接請求某個網址,返回結果在rep1中,如果有錯誤,錯誤碼保存在ec中
auto rep2 = asio2::http_client::execute("127.0.0.1", "8080", req2); // 通過IP端口以及前面生成的req2請求對象來發送一個http請求
std::cout << rep2 << std::endl; // 顯示http請求結果
std::stringstream ss;
ss << rep2;
std::string result = ss.str(); // 通過這種方式將http請求結果轉換為字符串

 

其它的HTTP使用方式以及WEBSOCKET使用方式請參考demo代碼

?

ICMP:

class ping_test // 模擬在一個類對象中使用ping組件(其它所有如TCP/UDP/HTTP等組件一樣可以在類對象中使用)
{
    asio2::ping ping;
public:
    ping_test() : ping(10) // 構造函數傳入的10表示只ping 10次后就結束,傳入-1表示一直ping
    {
        ping.timeout(std::chrono::seconds(3)); // 設置ping超時
        ping.interval(std::chrono::seconds(1)); // 設置ping間隔
        ping.body("0123456789abcdefghijklmnopqrstovuxyz");
        ping.bind_recv(&ping_test::on_recv, this) // 綁定當前這個類的成員函數作為監聽器
            .bind_start(std::bind(&ping_test::on_start, this, std::placeholders::_1)) // 也是綁定成員函數
            .bind_stop([this](asio::error_code ec) { this->on_stop(ec); }); // 綁定lambda
    }
    void on_recv(asio2::icmp_rep& rep)
    {
        if (rep.lag.count() == -1) // 如果延時的值等于-1表示超時了
            std::cout << "request timed out" << std::endl;
        else
            std::cout << rep.total_length() - rep.header_length()
                << " bytes from " << rep.source_address()
                << ": icmp_seq=" << rep.sequence_number()
                << ", ttl=" << rep.time_to_live()
                << ", ms"
                << std::endl;
    }
    void on_start(asio::error_code ec)
    {
        printf("start : %d %s\n", asio2::last_error_val(), asio2::last_error_msg().c_str());
    }
    void on_stop(asio::error_code ec)
    {
        printf("stop : %d %s\n", asio2::last_error_val(), asio2::last_error_msg().c_str());
    }
    void run()
    {
        if (!ping.start("127.0.0.1"))
        //if (!ping.start("123.45.67.89"))
        //if (!ping.start("stackoverflow.com"))
            printf("start failure : %s\n", asio2::last_error_msg().c_str());
        while (std::getchar() != '\n');
        ping.stop();
        // ping結束后可以輸出統計信息,包括丟包率,平均延時時長等
        printf("loss rate : %.0lf%% average time : %lldms\n", ping.plp(),
            std::chrono::duration_cast(ping.avg_lag()).count());
    }
};

?

SSL:?

TCP/HTTP/WEBSOCKET均支持SSL功能(需要在config.hpp中將#define ASIO2_USE_SSL宏定義放開)

asio2::tcps_server server;
// 從內存字符串加載SSL證書(具體請查看demo代碼)
server.set_cert("test", cer, key, dh); // cer,key,dh這三個字符串的定義請查看demo代碼
// 從文件加載SSL證書
//server.set_cert_file("test", "server.crt", "server.key", "dh512.pem");

  

TCP/HTTP/WEBSOCKET服務端、客戶端等SSL功能請到DEMO代碼中查看。

  

串口:

請查看demo示例代碼serial port 部分

?

其它:

定時器

// 框架中提供了定時器功能,使用非常簡單,如下:
asio2::timer timer;
// 參數1表示定時器ID,參數2表示定時器間隔,參數3為定時器回調函數
timer.start_timer(1, std::chrono::seconds(1), [&]()
{
    printf("timer 1\n");
    if (true) // 滿足某個條件時關閉定時器,當然也可以在其它任意地方關閉定時器
        timer.stop_timer(1);
});

  

還有其它一些輔助類的功能,請在源碼或使用中去體會吧.

?

?

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費