一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - 詳解Swoole TCP流數據邊界問題解決方案

詳解Swoole TCP流數據邊界問題解決方案

2021-11-18 14:39八重櫻 PHP教程

本文主要介紹了Swoole TCP流數據邊界問題解決方案,對Swoole感興趣的同學,可以參考下。

1. 數據發送過程

首先由客戶端將數據發往緩沖區 (服務端并不是直接收到的), 對于客戶端來說,這次的數據即是發送成功了, 對于服務端是否真正的收到他是不知道的, 然后再由服務端從緩沖區中讀取數據。圖解:

詳解Swoole TCP流數據邊界問題解決方案

2. 什么是數據邊界

因為 tcp 是流式傳輸,對于服務端來說并不知道此時在緩沖區內的數據是一次請求還是兩次請求的,所以在服務端接收數據時需要根據指定字符或約定長度來對數據進行分包,這個分包的標志即是數據邊界。否則可能會出現一次讀取兩條或多條數據,造成讀取、解析數據出錯。

詳解Swoole TCP流數據邊界問題解決方案

2.1 代碼演示

可以用代碼實現一下,假設客戶端死循環往緩沖區不停輸入 “1”,即相當于每次的報文內容都是 1, 那么在服務端讀取時收到的數據就是隨機長度的。

客戶端代碼:

服務端代碼:

運行結果

詳解Swoole TCP流數據邊界問題解決方案

可以看到運行結果,服務端獲取到的數據完全是隨機的,有長有短,那么接下來我們說下如何解決這個問題。

3.eof 解決方案

第一種解決方案類似于我們 http 請求頭的分隔符,在每次發送的數據包結尾處使用 \r\n (可以配置) 來結尾, 當服務端從緩沖區中讀取數據, 根據指定字符來分割數據包,eof 有兩種配置方案:

3.1 open_eof_check

首先放出配置方式:

這種配置方式會對客戶端發來的數據包進行檢測, 當發現結尾是 \r\n 時,才會投遞給 worker 進程, 也就是我們的 onreceive 回調,否則會一直拼接數據包,直到超出緩沖區或者超時才終止。 但此方法有一個問題是可能會一次性收到多個數據包,因為他是從數據包的結尾處來進行檢查的,在數據內容中存在 \r\n 時程序并不會發現,需要我們自己在應用代碼中再次使用 \r\n 來拆分數據包。

客戶端運行代碼

服務端代碼

運行結果

詳解Swoole TCP流數據邊界問題解決方案

3.2 open_eof_split

配置方式:

這種配置方式,服務端會對客戶端發來的數據逐個字符進行檢查,遇到 \r\n 就發送給 worker 進程,可以有效實現分包,但缺點是性能比較差。

運行結果:可以看到每次接收到一個 hello world(代碼我就不貼了, 只把服務端 set 配置改一下, 其他都一樣)

詳解Swoole TCP流數據邊界問題解決方案

3.3 open_eof_check 和 open_eof_split 差異

open_eof_check 只檢查接收數據的末尾是否為 eof,因此它的性能最好,幾乎沒有消耗

open_eof_check 無法解決多個數據包合并的問題,比如同時發送兩條帶有 eof 的數據,底層可能會一次全部返回

open_eof_split 會從左到右對數據進行逐字節對比,查找數據中的 eof 進行分包,性能較差。但是每次只會返回一個數據包

4. 固定包頭 + 包體解決方案

引用一段官方文檔的描述:

包長檢測提供了固定包頭 + 包體這種格式協議的解析。啟用后,可以保證 worker 進程 onreceive 每次都會收到一個完整的數據包。

長度檢測協議,只需要計算一次長度,數據處理僅進行指針偏移,性能非常高,推薦使用。

可見官方是推薦使用這種方式的,就是配置比其他方案要復雜一些, 首先貼一下配置:

下面是一個數據包結構例子,可以很好的體現了字段含義。

詳解Swoole TCP流數據邊界問題解決方案

以上通信協議的設計中,包頭長度為 4 個整型,16 字節,length 長度值在第 3 個整型處。因此 package_length_offset 設置為 8,0-3 字節為 type,4-7 字節為 uid,8-11 字節為 length,12-15 字節為 serid。

下面來說一下代碼實現:

客戶端代碼:

服務端代碼:

客戶端運行結果

詳解Swoole TCP流數據邊界問題解決方案

服務端運行結果

詳解Swoole TCP流數據邊界問題解決方案

可以看到 客戶端成功的把發送的數據回顯, 服務端也打印出了接收到的所有數據, 其中有些字段在發送時是 16 進制的, 所以服務端在接收到之后需要進行進制轉換, 我這里沒有進行轉換, 所以顯示的數據是 10 進制的。

5. 總結

通過對比可以看出使用固定包頭 + 包體的方式是效率最高的一種, 因為他是按照固定長度去讀取的。期間專門去了解了 pack 函數的使用方法,但也不確定這么寫到底對不對,如果有其他了解的仁兄可以慷慨解答一下,網上相關資料有點少,官方文檔上也只給出了幾個字段的釋義。

6. 擴展知識

6.1 字節序

計算機硬件有兩種儲存數據的方式:大端字節序(big endian)和小端字節序(little endian)。

舉例來說,數值 0x2211 使用兩個字節儲存:高位字節是 0x22,低位字節是 0x11。

  • 大端字節序:高位字節在前,低位字節在后,這是人類讀寫數值的方法。
  • 小端字節序:低位字節在前,高位字節在后,即以 0x1122 形式儲存。

這個前和后指的是內存地址,計算機處理字節時是不知道高低字節之分的,它只知道按順序讀取字節,先讀第一個字節,再讀第二個字節。

例如: 0x1234567 的讀取順序:

詳解Swoole TCP流數據邊界問題解決方案

以上就是詳解swoole tcp流數據邊界問題解決方案的詳細內容,更多關于swoole tcp流數據邊界問題解決方案的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/a609251438/p/12931377.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 波多野结衣 在线 | brazzersxxx欧美 | 无码人妻视频又大又粗欧美 | 国产婷婷成人久久av免费高清 | 国产欧美国产精品第一区 | 欧美国产合集在线视频 | tobu8中国在线观看免费视频 | 欧美性黑人巨大gaysex | 亚洲可乐操 | 欧美夜夜精品一级爽 | 99爱在线精品视频免费观看9 | 精品在线一区 | 精品福利一区二区免费视频 | 日本男男gaygays | 91国语自产拍在线观看 | 国产日韩欧美 | 大伊人青草狠狠久久 | juliaann大战两个黑人 | 亚洲欧美日韩国产精品影院 | 唯美 清纯 另类 亚洲制服 | www.亚洲视频| 99视频精品全部免费观看 | 国产一区二区三区在线看 | 国产麻豆精品入口在线观看 | 扒开放荡老师裙子猛烈的进入 | 女人被爽到呻吟娇喘的视频动态图 | 日本www午夜色在线视频 | 97色综合| 国产美女亚洲精品久久久综合91 | 喷潮女王cytherea全部视频 | 师尊被各种play打屁股 | 亚洲精品一区波多野结衣 | 大肚孕妇的高h辣文 | 高h视频免费观看 | 欧美一区二区三区免费不卡 | 动漫a级片 | 日处女b | 国产午夜永久福利视频在线观看 | 国产日产国无高清码2020 | 99青青青精品视频在线 | 猛h辣h高h文湿校园1v1 |