C/S框架 st_asio_wrapper開發教程(2019.10.17更新)(三)

如果你偶然瀏覽到這裏,請先看 C/S框架 st_asio_wrapper 開發教程(一)
源代碼及例程下載地址:
git:https://github.com/youngwolf-project/st_asio_wrapper/
QQ交流羣:198941541

七:自定義數據結構支持

當st_asio_wrapper server與其它客戶端、或者st_asio_wrapper client與其它服務端通信時,需要自定義消息結構(除非協議剛好爲默認打包解包器的協議——2字節包長加消息內容),具體如下(接收):
        1.從i_packer和i_unpacker繼承,生成自己的打包解包器;
        2.調用packer()和unpacker()修改打包解包器;
        3.如果考慮通用性的話,打包解包器應該要支持原始消息的打包(此時只做數據拼接,不添加任何協議)。pack_msg接口的最後一個參數用於表達是否是打原始消息包(即,pack_msg是從send_msg還是從send_native_msg調用的);
        4.接收緩存必須放在解包器之內,當收到數據時,st_asio_wrapper會調用解包器的parse_msg接口,解包器應在這裏面解包,並將結果通過msg_can參數返回出去;
        5.調用parse_msg之後,st_asio_wrapper馬上開始下一次數據接收(除非定義了ST_ASIO_PASSIVE_RECV宏),此時會調用解包器的prepare_next_recv接口,這個接口負責返回一個緩存(能被asio::async_read使用的任何緩存對象均可);
        6.重寫completion_condition接口,這個接口用於判斷什麼時候可以解析消息了(即調用parse_msg),顯然,至少收到一條完整的消息之後,就可以解析了;返回0代表可以解析消息了(或者說出錯了),返回其它值代表至少還需要多少字節,才能解析;這些說起來很抽象,大家看一下默認的解包器的實現就清楚了。

發送:
        1.如果你只是發送自定義數據結構,則默認st_asio_wrapper已經實現了,就是調用send_native_msg接口來發送消息,前提是,你在調用之前,數據已經組裝打包好了;
        2.自定義數據結構仍然在on_msg和on_msg_handle裏面接收處理消息;

        好的消息結構應該是 包頭 + 長度 + 數據,其中包頭可以沒有,如果每一個消息的長度都是定長的,則也可以沒有長度,但不要包頭和長度全都沒有。爲什麼這是好的消息結構呢,因爲這樣可以減少boost.asio的回調次數,也就提高了執行效率。

        一但使用自定義數據結構,二次開發者不得不自己處理粘包,分包,解包,數據緩存等工作,也就是實現自己的打包解包器。關於打包解包器的更多信息,請參考st_asio_wrapper自帶的packer和unpacker。

八:ipv6支持

        st_asio_wrapper支持ipv6,demo裏面有代碼演示(註釋狀態,去掉註釋開啓ipv6,注意服務端和客戶端都得開啓),服務端我們往往不指定ip,那麼st_asio_wrapper就推導不出來ip協議的版本來,此時可以通過定義ST_ASIO_DEFAULT_IP_VERSION宏來指定版本,具體請參看教程——宏

九:發送接收消息緩存,以tcp::socket_base爲例,udp::socket_base同理
        這兩個緩存與unpacker裏面的緩存概念不一樣,unpacker的緩存是boost.asio使用的最原始的緩存,且一般應該是固定大小的,tcp::socket_base的發送接收消息緩存裏面保存的都是消息,可以直接取出來使用而不需要解包的,其大小總字節數參看教程——宏
        發送緩存爲什麼需要,我想不用解釋了吧(如果在send_msg中,不緩存消息,而是直接投遞async_write會怎樣呢?這樣的確是不需要發送緩存了,但多次的async_write投遞,會造成包亂序,這幾乎是無法解決並且不可容忍的問題,而且投遞的async_write數量也是不定的,內存佔用不可控,所以st_asio_wrapper::socket採用了發送緩存,每次只投遞一個async_write,等到發送成功之後,再投遞下一個)。對於接收消息緩存,其作用就是讓消息接收與分發(回調on_msg_handle)併發,如果你確實不想用接收緩存,可以在parse_msg裏面通過自己的邏輯來派發消息,永遠不返回消息,這樣就不會使用接收緩存了。

        st_asio_wrapper保證消息按照順序發送、接收和分發(on_msg_handle),所以你完全不用擔心消息亂序的問題。當然,順序接收得說兩句,接收端是不知道發送端的順序的,所以順序接收要建立在順序發送的基礎之上。

C/S框架 st_asio_wrapper 開發教程(四)

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