婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案

詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案

熱門標簽:凱立德地鐵站地圖標注 溫州外呼系統(tǒng)招商 手機外呼系統(tǒng)什么原理 天津電銷外呼系統(tǒng)違法嗎 400電話個人能不能辦理 銀行信貸電話機器人 合肥ai電銷機器人費用 滄州電銷外呼系統(tǒng)價格 上海400客服電話怎么申請

1. 數(shù)據(jù)發(fā)送過程

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

2. 什么是數(shù)據(jù)邊界

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

2.1 代碼演示

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

客戶端代碼:

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if ($client->connect('127.0.0.1', 9501, -1)) {
    while(true) {
        $client->send(1);        
    }
}
$client->close();

服務端代碼:

$server = new Swoole\Server('127.0.0.1', 9501);
$server->on('connect', function($server, $fd){
    echo "client : ".$fd." connect";
});

$server->on('receive', function($server, $fd, $from_id, $data){
    echo "receive:". $data.PHP_EOL;
});

$server->on('close', function($server){

});

運行結果

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

3.EOF 解決方案

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

3.1 open_eof_check

首先放出配置方式:

$server->set([
    'open_eof_check' => true,
    'package_eof' => "\r\n"
]);

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

客戶端運行代碼

$client = new Swoole\Client(SWOOLE_SOCK_TCP);

if ($client->connect('127.0.0.1', 9501, -1)) {

    while(true) {
        $send2 = "Hello World \r\n";
        $client->send($send2);        
    }
}

$client->close();

服務端代碼

$server = new Swoole\Server('127.0.0.1', 9501);
$server->set([
    'open_eof_check' => true,
    'package_eof' => "\r\n"
]);

$server->on('connect', function($server, $fd){
    echo "client : ".$fd." connect";
});

$server->on('receive', function($server, $fd, $from_id, $data){
    echo "receive:". $data;
});

$server->on('close', function($server){

});

$server->start();

運行結果

3.2 open_eof_split

配置方式:

$server->set([
    'open_eof_split' => true,
    'package_eof' => "\r\n"
]);

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

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

3.3 open_eof_check 和 open_eof_split 差異

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

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

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

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

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

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

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

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

$server->set([
// 打開包長檢測特性
'package_length_check' => true,
// 包頭中某個字段作為包長度的值,底層支持了 10 種長度類型。可參考 pack() 方法
'package_length_type' => 'N',
// length 長度值在包頭的第幾個字節(jié)。
'package_length_offset' => 8,
// 從第幾個字節(jié)開始計算長度,一般有 2 種情況:
//length 的值包含了整個包(包頭 + 包體),package_body_offset 為 0
//包頭長度為 N 字節(jié),length 的值不包含包頭,僅包含包體,package_body_offset 設置為 N
'package_body_offset' => 16,
// 設置最大數(shù)據(jù)包尺寸,單位為字節(jié)
'package_max_length' => 81920
]);

下面是一個數(shù)據(jù)包結構例子,可以很好的體現(xiàn)了字段含義。

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

下面來說一下代碼實現(xiàn):

客戶端代碼:

$client = new Swoole\Client(SWOOLE_SOCK_TCP);

$data = "123456789012345678901234567890";
$type = 0x30;
$uid = 0x123;
$length = strlen($data);
$serid = 0x15;
$head = pack("N4", $type, $uid, $length, $serid);
$body = pack("a{$length}", $data);
$message = $head.$body;


if ($client->connect('127.0.0.1', 9502, -1)) {
    $client->send($message);
    echo $client->recv();
}

$client->close();

服務端代碼:

$serv = new Swoole\Server('127.0.0.1', 9502);
$serv->set([
    'open_length_check'     => true,
      'package_max_length'    => 81920,
      'package_length_type'   => 'N',
      'package_length_offset' => 8,
      'package_body_offset'   => 16,    
]);

$serv->on('connect', function($server, $fd){
    echo $fd. " Connect !".PHP_EOL;
});

$serv->on('receive', function($server, $fd, $from_id, $data){
    var_dump($data);            // 源數(shù)據(jù)
    $tmp = unpack("Ntype/Nuid/Nlength", $data);
    $unpacking = unpack("Ntype/Nuid/Nlength/Nserid/a{$tmp['length']}body", $data);
    var_dump($unpacking);        // 解包后數(shù)據(jù)
    $server->send($fd, " Server Receive Data: ". $unpacking['body']);
});


$serv->on('close', function($server){

});

$serv->start();

客戶端運行結果

服務端運行結果

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

5. 總結

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

6. 擴展知識

6.1 字節(jié)序

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

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

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

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

例如: 0x1234567 的讀取順序:

以上就是詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案的詳細內(nèi)容,更多關于Swoole TCP流數(shù)據(jù)邊界問題解決方案的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • 詳解PHP Swoole與TCP三次握手
  • Swoole擴展的6種模式深入詳解
  • php中Swoole的熱更新實現(xiàn)代碼實例
  • swoole鎖的機制代碼實例講解
  • windows系統(tǒng)php環(huán)境安裝swoole具體步驟
  • linux系統(tǒng)虛擬主機開啟支持Swoole Loader擴展的方法
  • Swoole源碼中如何查詢Websocket的連接問題詳解
  • 在Windows系統(tǒng)上安裝Cygwin搭建Swoole測試環(huán)境的圖文教程
  • php使用goto實現(xiàn)自動重啟swoole、reactphp、workerman服務的代碼
  • Centos7安裝swoole擴展操作示例

標簽:白城 怒江 金華 酒泉 溫州 七臺河 洛陽 赤峰

巨人網(wǎng)絡通訊聲明:本文標題《詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案》,本文關鍵詞  詳解,Swoole,TCP,流,數(shù)據(jù),邊界,;如發(fā)現(xiàn)本文內(nèi)容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案》相關的同類信息!
  • 本頁收集關于詳解Swoole TCP流數(shù)據(jù)邊界問題解決方案的相關信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    精品久久一二三区| 亚洲午夜激情网页| 91精品国产一区二区三区香蕉| 国产成人亚洲综合a∨婷婷| 视频在线观看国产精品| 亚洲一区二区精品久久av| 精品国产污网站| 99国内精品久久| av电影天堂一区二区在线| 国产高清亚洲一区| 国产精品18久久久久久久久| 蜜臀av性久久久久蜜臀aⅴ| 偷拍与自拍一区| 午夜精品久久久久久久久| 久久婷婷成人综合色| 精品人在线二区三区| 日韩美女视频在线| 精品国产一区久久| 日韩欧美高清dvd碟片| 欧美成人欧美edvon| 精品久久一区二区| 国产亚洲1区2区3区| 欧美高清在线精品一区| 精品久久久久一区二区国产| 精品乱码亚洲一区二区不卡| 337p粉嫩大胆色噜噜噜噜亚洲 | 欧美不卡视频一区| 日韩免费电影一区| wwwwxxxxx欧美| 中文字幕欧美一| 一个色在线综合| 亚洲国产精品视频| 乱一区二区av| 成人性生交大片免费看中文| 91啪亚洲精品| 制服.丝袜.亚洲.中文.综合| 精品美女一区二区三区| 日本一区二区在线不卡| 亚洲丝袜精品丝袜在线| 国产精品久久综合| 一区二区三区精品久久久| 日日夜夜免费精品| 国内精品国产成人国产三级粉色| 成人激情免费电影网址| 欧美伊人久久大香线蕉综合69 | 色综合中文字幕国产 | 亚洲乱码国产乱码精品精小说 | 亚洲成年人影院| 精品一区二区免费在线观看| 99久久久无码国产精品| 欧美色视频在线观看| 久久久国产午夜精品| 亚洲一区二区av在线| 韩国精品主播一区二区在线观看| 日本一区中文字幕| 99国产精品国产精品毛片| 欧美一级午夜免费电影| 国产精品国产自产拍高清av| 蜜桃视频在线一区| 成人美女视频在线观看18| 91麻豆精品国产91久久久久久久久 | 欧美国产一区在线| 亚洲国产精品久久久久婷婷884| 国产一区二区在线电影| 欧美体内she精视频| 精品区一区二区| 亚洲第一成人在线| 97久久人人超碰| 久久精品人人爽人人爽| 蜜臀av亚洲一区中文字幕| 在线观看一区二区视频| 国产精品三级在线观看| 日韩一区精品视频| 91福利国产精品| 国产精品理论片在线观看| 精彩视频一区二区| 欧美精品三级在线观看| 久久蜜臀中文字幕| 久久69国产一区二区蜜臀| 777奇米四色成人影色区| 亚洲一区二区三区影院| 99久久婷婷国产| 中文字幕欧美激情| 免费的成人av| 欧美一区二区三区精品| 天天影视网天天综合色在线播放| 99re视频这里只有精品| 国产精品夫妻自拍| 国产精品影视网| 久久日一线二线三线suv| 麻豆精品精品国产自在97香蕉| 欧美另类高清zo欧美| 亚洲午夜久久久久久久久电影网 | 在线看不卡av| 国产欧美一区二区三区网站| 国产综合久久久久久鬼色| 欧美大片拔萝卜| 乱一区二区av| 国产日韩欧美一区二区三区乱码| 亚洲成人激情av| 日韩午夜在线影院| 久99久精品视频免费观看| 精品美女在线播放| 美女国产一区二区| 久久久精品天堂| 国产精品18久久久久久久久| 国产精品蜜臀av| 欧美怡红院视频| 美日韩一区二区三区| 久久久国产一区二区三区四区小说| 国产伦精品一区二区三区免费迷 | 欧美精品一二三四| 国产福利精品一区二区| 日韩中文欧美在线| 国产天堂亚洲国产碰碰| 7777精品伊人久久久大香线蕉| 国产凹凸在线观看一区二区| 日韩极品在线观看| 亚洲视频小说图片| 欧美成人女星排名| 欧美欧美欧美欧美| 91丝袜美腿高跟国产极品老师| 久久国产婷婷国产香蕉| 婷婷国产在线综合| 亚洲精品乱码久久久久久| 久久精品男人天堂av| 日韩欧美精品在线| 欧美这里有精品| 91美女福利视频| 成人av资源网站| 国产精品一级片| 韩国一区二区在线观看| 日韩不卡免费视频| 天堂蜜桃91精品| 亚洲国产精品影院| 亚洲制服丝袜av| 亚洲色图在线视频| 中文字幕乱码日本亚洲一区二区| 欧美tk—视频vk| 欧美一区二区三区四区五区 | 91久久精品国产91性色tv| 国产精品18久久久久久久久| 国产麻豆精品视频| 国产福利不卡视频| 成人国产精品免费观看视频| 国产精品自拍毛片| 国产成人精品在线看| 国产成人在线视频网址| 紧缚捆绑精品一区二区| 国产一区二区三区在线看麻豆| 美国毛片一区二区| 国产一区二区三区在线观看免费 | 久久疯狂做爰流白浆xx| 久久不见久久见免费视频1| 久久99精品久久久久| 国产一区二区三区四| 丁香激情综合五月| 色哟哟一区二区在线观看| 在线观看亚洲a| 91精品免费观看| 26uuu欧美| 国产精品国产三级国产普通话蜜臀 | 制服.丝袜.亚洲.另类.中文| 香蕉av福利精品导航| 中文字幕欧美激情| 亚洲欧洲日本在线| 亚洲国产人成综合网站| 蜜臀久久99精品久久久久宅男| 精品在线一区二区三区| 成人小视频在线| 日本韩国一区二区| 日韩三级视频在线看| 亚洲国产高清在线| 亚洲午夜久久久久中文字幕久| 捆绑调教一区二区三区| 国内精品在线播放| 91激情在线视频| 免费精品视频在线| 91精品国产综合久久福利| eeuss鲁一区二区三区| 欧美吞精做爰啪啪高潮| 精品成人一区二区| 亚洲视频在线一区| 韩国成人福利片在线播放| 99久久免费精品| 日韩三级精品电影久久久 | 在线观看不卡视频| 日韩久久精品一区| 亚洲一区二区三区影院| 国产一区二区影院| 欧美午夜影院一区| 国产日产欧美一区二区三区| 亚洲第一狼人社区| 波多野洁衣一区| 337p粉嫩大胆噜噜噜噜噜91av| 亚洲另类春色校园小说| 国产久卡久卡久卡久卡视频精品| 在线中文字幕一区二区| 日本一二三四高清不卡| 麻豆精品一区二区av白丝在线|