日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netplus里的基本概念

發布時間:2023/12/18 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netplus里的基本概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

本文為初見,Netplus快速開始之PingPong Example系列第三篇


1. netp::ref_ptr & netp::ref_base

C++是一門面向對象的語言,一切皆可為對象,然對象的創建與銷毀,指針的傳遞、共享,在稍大一點的工程里面,如豆腐雕花,如履薄冰,一不小心,直接崩壞,尤其是引入多線性以及異步編程之后,更是令人心力交瘁,這種動不動就出王炸的逆天脾氣,常使得開發者談C色變。

那么對象的管理,到底有沒有好一點的辦法呢,netplus選擇了ref_ptr&ref_base, 顧名思義,這是一種基于引用計數的對象管理機制,因篇幅關系,這里暫時只講如何使用它。

  • 在Netplus里面,絕大部分的class都繼承于ref_base,ref_base作為根,提供引用計數的基本功能。
  • 繼承自ref_base的class,直接new/delete 的時候,編譯器會報錯。
  • 繼承netp::ref_base的class,需要配合模板netp::ref_ptr<T>進行使用。
  • netp::ref_ptr<T>對象,只能通過netp::make_ref<T> 進行創建,不需要的時候,需賦值為nullptr。
  • 每賦值給一次,引用計數增1,每被置nullptr一次,引用計數減1,當減到0的時候,其指向的內存將被回收,賦值是線程安全的。
  • netp::ref_ptr<T>可以如指針 T* 一樣用來訪問其指向的對象。
  • sizeof(netp::ref_ptr<T>) == sizeof(T*)。
  • 更詳細的知識,請參:

Netplus 之 Smart Pointer?github.com

  • 下面是一個關于 ref_ptr&ref_base 的example
class ref_example: public netp::ref_base {int number;public:ref_example(int i):number(i){}int get_number() {return number;}void set_number(int i) {number=i;} };//創建,記住,不能直接new/delete, 只能借助 netp::make_ref 函數; netp::ref_ptr<ref_example> ref_example_1 = netp::make_ref<ref_example>(10);//可像裸指針一樣訪問對象 ref_example_1 ->set_number(10); int number_value = ref_example_1 ->get_number();//賦值,它是線程安全的 netp::ref_ptr<ref_example> ref_example_2 = ref_example_1;{ //它是容器安全的,可在各容器里面自由存儲std::vector<netp::ref_ptr<ref_example>> ref_example_vector; ref_example_vector.push_back(ref_example_2); }//比較,注意,這里比較的是指向的地址 if( ref_example_2 == ref_example_1 ) { //比較兩個ref_ptr對象是否指向同一個對象 }//ref_ptr對象的大小 == 機器的地址寬度,試想一下,將有何好處? //sizeof(netp::ref_ptr<ref_example>) == sizeof(int*);//銷毀, 不需要的時候,我們直接置nullptr即可 ref_example_1 = nullptr; ref_example_2 = nullptr;//借助于C++ RAII特性,局部變量,我們甚至都不用去置nullptr {netp::ref_ptr<ref_example> ref_example_3 = netp::make_ref<ref_example>(10); //離開此作用域后, ref_example_3指向的內存將自動被釋放 }

是不是覺得,c++的對象管理也可以很自然,很簡單,很符合直覺。^_^

2. Packet

  • Packet是Netplus的一個重要Class, 繼承自netp::ref_base,它提供用于讀寫bytes buffer的接口,是我們用來操作bytes buffer的工具。
  • 網絡編程中,當處理Bytes Buffer,特別是處理protocol時,我們需要讀或修改頭部,或直接往頭部前面添加一些數據。Packet被專門設計成應對這種場景,它既可以往buffer的左邊寫,也可以在buffer末端往前寫,于是,處理起來將變得極為方便。
  • Channel將收到的bytes, 存儲在Packet對象里面,然后再將此對象傳遞給它的第一個Handler。
  • 往遠端寫bytes的時候,我們也是將bytes存儲于一個Packet對象,然后最終傳遞給Channel。
  • Example:
//創建一個packet對象 netp::ref_ptr<netp::packet> p = netp::make_ref<netp::packet>();//寫入一個字符串 p->write("hello", netp::strlen("hello") );//將字符串讀入buf //注:byte_t 實為unsigned char netp::byte_t hello_buf[10]={0}; netp::u32_t read_count = p->read(hello_buf, 10);//在packet buf的左邊寫入一個u32_t大小的整數 p->write_left<netp::u32_t>(103);//將剛剛寫入的整數讀入i103 netp::u32_t i103 = p->read<u32_t>();//銷毀packet對象 p = nullptr;

3. Channel

  • Channel是網絡通信的主體,它即是當前的連接,它也是最終與操作系統進行交互,讀寫bytes,以及socket狀態管理的實體。
  • 每一個Channel可以添加一個多個Channel Handler,Channel Handler以單向鏈表的形式鏈接在一起,當與Channel相關的事件發生的時候,Channel負責將事件傳遞給第一個Channel Handler。
  • 一個典型的channel read事件,按下面順序在Handler中傳遞
socket read -> channel -> tail_handler -> handler1 -> handler2 -> ...
  • 一個典型的channel write事件,按下面順序在Handler中傳遞
head_handler -> ... -> handler2 -> handler1 -> tail_handler -> channel -> socket write
  • 每一個handler在創建的時候都會包含一個tail handler, 一個head handler,用于處理缺省行為

4. Channel Handler

  • Channel Handler是具體處理我們的消息的地方,處理完消息后,我們可以繼續傳遞一個消息給下一個Handler,或直接終止當前消息的邏輯處理,甚至接關閉當前的Channel。
  • Channel Handler需要繼承 netp::channelhandler_abstract, 實現相應接口,用于處理網絡事件,消息。
  • 更多細節,請參:

Netplus 之 Concepts?

?

  • 在我們的例子中,我們將用到如下Channel handler接口
void read(netp::ref_ptr<netp::channel_handler_context> const& ctx, netp::ref_ptr<netp::packet> const& income); void connected(netp::ref_ptr<netp::channel_handler_context> const& ctx);

?

下文我們聊一下在Netplus里面,實現一個服務器,客戶端的基本流程

?

寫代碼的冰冰

?

總結

以上是生活随笔為你收集整理的Netplus里的基本概念的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。