溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么自定義協(xié)議

發(fā)布時(shí)間:2021-10-21 10:15:24 來(lái)源:億速云 閱讀:136 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“怎么自定義協(xié)議”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

為什么要自定義協(xié)議

直接使用標(biāo)準(zhǔn)的協(xié)議好處是顯而易見(jiàn)的,我個(gè)人理解的幾點(diǎn)優(yōu)點(diǎn):

  • 既然是標(biāo)準(zhǔn)協(xié)議說(shuō)明已經(jīng)成為了標(biāo)準(zhǔn),這樣很多系統(tǒng)就可以直接對(duì)接,無(wú)縫集成;

  • 協(xié)議最重要的一點(diǎn)就是編碼解碼,標(biāo)準(zhǔn)協(xié)議往往有現(xiàn)成的編碼解碼包,直接拿來(lái)使用,減少開(kāi)發(fā)時(shí)間;

  • 有很多圍繞標(biāo)準(zhǔn)協(xié)議的第三方測(cè)試工具,可以很方便的進(jìn)行測(cè)試;

既然有這么多優(yōu)點(diǎn)那我們?yōu)槭裁催€要去自定義協(xié)議,大致出于以下幾點(diǎn)考慮:

  • 既然是標(biāo)準(zhǔn)協(xié)議,往往兼顧的東西比較多,導(dǎo)致協(xié)議數(shù)據(jù)相對(duì)來(lái)說(shuō)比較大,這樣可能在一些追求性能,流量的系統(tǒng)中不能容忍;

  • 標(biāo)準(zhǔn)協(xié)議有很多,沒(méi)有哪一種協(xié)議可以適用任何場(chǎng)景中,所以如果在某個(gè)場(chǎng)景中還沒(méi)有既定的標(biāo)準(zhǔn)協(xié)議,這時(shí)候會(huì)有各種私有協(xié)議;

  • 自定義協(xié)議只要雙方約定好數(shù)據(jù)結(jié)構(gòu)就行,不具有通用性,理論上來(lái)說(shuō)會(huì)更加安全一點(diǎn),當(dāng)然現(xiàn)在很多標(biāo)準(zhǔn)協(xié)議都有安全版本,比如https,sftp等等;

以上只是個(gè)人的一點(diǎn)理解,歡迎大家補(bǔ)充;關(guān)于如何去自定義協(xié)議,其實(shí)可以去多參考一些主流的標(biāo)準(zhǔn)協(xié)議或者私有協(xié)議,其實(shí)有很多共同點(diǎn)可以去借鑒;下面先簡(jiǎn)單看看那些主流的協(xié)議;

主流協(xié)議

下面分別看看一些主流的標(biāo)準(zhǔn)協(xié)議或者私有協(xié)議都是如何去定義自己的數(shù)據(jù)結(jié)構(gòu)的,對(duì)我們有非常好的借鑒意義;

http協(xié)議

http協(xié)議大家最熟悉不過(guò)了,全稱叫超文本傳輸協(xié)議,整個(gè)請(qǐng)求報(bào)文可以分為三個(gè)部分分別是:請(qǐng)求行,請(qǐng)求報(bào)頭,請(qǐng)求正文;

  • 請(qǐng)求行

GET /test.html HTTP/1.1 (CRLF換行)
  • 請(qǐng)求報(bào)頭

Accept-Encoding: gzip, deflateContent-Length: 38 Content-Encoding: gzip...

請(qǐng)求包頭有很多,每一個(gè)代表了各自的含義,這邊就不一一列出,我們這里更加關(guān)注整個(gè)報(bào)文的結(jié)構(gòu);

  • 請(qǐng)求正文

這個(gè)只有在POST請(qǐng)求的時(shí)候才有正文,里面存放業(yè)務(wù)數(shù)據(jù),比如常見(jiàn)的json文本串;具體正文的長(zhǎng)度可以根據(jù)消息頭中的Content-Length來(lái)決定;

dubbo協(xié)議

dubbo協(xié)議格式可以直接參考官網(wǎng)提供的如下圖片:
怎么自定義協(xié)議
看上圖其實(shí)整個(gè)協(xié)議數(shù)據(jù)包也大致分為兩個(gè)部分:固定部分和可變部分,或者叫消息頭和消息體;
固定部分一共是4+8+4=16個(gè)字節(jié),具體如下所示:

header{Magic High       = 8bit;  //魔數(shù)高位Magic Low        = 8bit;  //魔數(shù)低位Req/Res          = 1bit;  //標(biāo)識(shí)是請(qǐng)求或響應(yīng)2 Way            = 1bit;  //標(biāo)記是否期望從服務(wù)器返回值Event            = 1bit;  //標(biāo)識(shí)是否是事件消息Serialization ID = 5bit;  //標(biāo)識(shí)序列化類型Status           = 8bit;  //標(biāo)識(shí)響應(yīng)的狀態(tài)Request ID       = 64bit; //標(biāo)識(shí)唯一請(qǐng)求Data Length      = 32bit; //序列化后的內(nèi)容長(zhǎng)度}

可變部分根據(jù)固定部分中的Data Length來(lái)確定長(zhǎng)度;

redis協(xié)議

Redis的客戶端與服務(wù)端采用叫做 RESP(Redis Serialization Protocol)的網(wǎng)絡(luò)通信協(xié)議交換數(shù)據(jù),相對(duì)來(lái)說(shuō)還是比較簡(jiǎn)單的,以下是這個(gè)協(xié)議的一般形式:

*< 參數(shù)數(shù)量 > CR LF
$< 參數(shù) 1 的字節(jié)數(shù)量 > CR LF< 參數(shù) 1 的數(shù)據(jù) > CR LF
...
$< 參數(shù) N 的字節(jié)數(shù)量 > CR LF< 參數(shù) N 的數(shù)據(jù) > CR LF

以上大致介紹了三種比較有代表性的協(xié)議,雖然說(shuō)每種協(xié)議都有各自的使用場(chǎng)景,但是如果我們自己去定義協(xié)議,還是有一些相通的東西;

如何自定義協(xié)議

下面我們重點(diǎn)看看去自定義協(xié)議有哪些需要我們關(guān)注的點(diǎn),以下是本人根據(jù)自己的理解整理了如下關(guān)注點(diǎn):

  • 完整的數(shù)據(jù)包

  • 協(xié)議號(hào)

  • 消息頭標(biāo)識(shí)

  • 業(yè)務(wù)數(shù)據(jù)

  • 預(yù)留字段

下面分別逐一詳細(xì)介紹:

完整的數(shù)據(jù)包

我們平時(shí)經(jīng)常講數(shù)據(jù)包,但是TCP其實(shí)只有流的概念,并沒(méi)有數(shù)據(jù)包的概念;那很重要的一點(diǎn)就是我們的程序怎么知道現(xiàn)在的業(yè)務(wù)數(shù)據(jù)已經(jīng)接受全部接收完了,可以作為一個(gè)完整的數(shù)據(jù)包去處理了,如果不去做處理的話就會(huì)出現(xiàn)我們常說(shuō)的半包和粘包問(wèn)題;主流的的處理方式大致有這么兩種:

  • 在消息頭部加上數(shù)據(jù)包長(zhǎng)度描述,比如在http協(xié)議和dubbo協(xié)議中出現(xiàn)的dataLength字段;

  • 用特殊的字符串作為數(shù)據(jù)包的結(jié)尾,這樣我們?cè)诮邮軘?shù)據(jù)的時(shí)候接受到預(yù)定的特殊字符串就表示數(shù)據(jù)包完整了;

協(xié)議號(hào)

可能不同的協(xié)議有不同的叫法,我這里把它叫做協(xié)議號(hào),個(gè)人理解就是根據(jù)這個(gè)協(xié)議號(hào),服務(wù)器端知道去執(zhí)行什么邏輯;比如http協(xié)議請(qǐng)求行中的/test.html,dubbo協(xié)議中的服務(wù)名+版本號(hào),redis中的具體要執(zhí)行什么key;

消息頭標(biāo)識(shí)

這個(gè)是否需要還是要看各自的場(chǎng)景,比如redis協(xié)議足夠簡(jiǎn)單,無(wú)需任何標(biāo)識(shí),所有的東西都是雙端約定好的;但是其他很多協(xié)議還是有一些需要的,除了上面說(shuō)到的可以在消息頭中指定dataLength,其實(shí)還有很多其他的東西可以指定比如:

  • 業(yè)務(wù)數(shù)據(jù)格式:文本格式,json格式,html格式等等;

  • 壓縮格式:可能為了追求流量包大小對(duì)數(shù)據(jù)包進(jìn)行壓縮,gzip、deflater、snappy等;

  • 加密算法:可能需要對(duì)我的業(yè)務(wù)數(shù)據(jù)進(jìn)行加密處理,保證業(yè)務(wù)數(shù)據(jù)的安全性AES、DES等;

業(yè)務(wù)數(shù)據(jù)

業(yè)務(wù)數(shù)據(jù)往往在整個(gè)數(shù)據(jù)包中是最大的,同時(shí)也是大小可變的部分;我們上面所做的這些其實(shí)都是在為業(yè)務(wù)數(shù)據(jù)服務(wù),業(yè)務(wù)數(shù)據(jù)需要在網(wǎng)絡(luò)傳輸,最重要的一點(diǎn)就是序列化,一般就以下兩種方式:

  • 文本方式:序列化文本文檔text,或者json串,xml格式等;

  • 二進(jìn)制方式:常見(jiàn)的比如protobuf,thrift,kyro等;

預(yù)留字段

是否需要預(yù)留字段這個(gè)得看情況,比如http協(xié)議整個(gè)消息頭是可變的,每一行一個(gè)標(biāo)識(shí),知道讀取到空行,表示消息頭結(jié)束下面就是正文了,可以理解為http使用了兩種方式來(lái)保證完整包,消息頭使用特殊字符結(jié)尾,正文使用在消息頭中指定dataLength;這種方式其實(shí)它的整個(gè)擴(kuò)展性是非常好的;
另外一種像dubbo這樣,其實(shí)它的頭部相當(dāng)于已經(jīng)固定好了16個(gè)字節(jié),這種情況下是否可以預(yù)留幾個(gè)字節(jié)防止后面的變更;

“怎么自定義協(xié)議”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI