自定義 如何自定義協議

2021-10-14 21:05:56 字數 2146 閱讀 1539

何為自定義協議,其實是相對標準協議來說的,這裡主要針對的是應用層協議;常見的標準的應用層協議如http、ftp、smtp等,如果我們在網路通訊的過程中不去使用這些標準協議,那就需要自定義協議,比如我們常用的rpc框架(dubbo,thrift),分布式快取(redis,memcached)等都是自定義協議;本文就來講講如何去自定義私有協議,在此之前我們先考慮一下為什麼要自定義協議。

直接使用標準的協議好處是顯而易見的,我個人理解的幾點優點:

既然有這麼多優點那我們為什麼還要去自定義協議,大致出於以下幾點考慮:

下面分別看看一些主流的標準協議或者私有協議都是如何去定義自己的資料結構的,對我們有非常好的借鑑意義;

get /test.html http/1.1 (crlf換行)

accept-encoding: gzip, deflate

content-length: 38

content-encoding: gzip

...

這個只有在post請求的時候才有正文,裡面存放業務資料,比如常見的json文字串;具體正文的長度可以根據訊息頭中的content-length來決定;

dubbo協議格式可以直接參考官網提供的如下:

header

可變部分根據固定部分中的data length來確定長度;

redis的客戶端與服務端採用叫做 **resp(redis serialization protocol)**的網路通訊協議交換資料,相對來說還是比較簡單的,以下是這個協議的一般形式:

*< 引數數量 > cr lf

$< 引數 1 的位元組數量 > cr lf

< 引數 1 的資料 > cr lf

...$< 引數 n 的位元組數量 > cr lf

< 引數 n 的資料 > cr lf

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

下面分別逐一詳細介紹:

我們平時經常講資料報,但是tcp其實只有流的概念,並沒有資料報的概念;那很重要的一點就是我們的程式怎麼知道現在的業務資料已經接受全部接收完了,可以作為乙個完整的資料報去處理了,如果不去做處理的話就會出現我們常說的半包和粘包問題;主流的的處理方式大致有這麼兩種:

可能不同的協議有不同的叫法,我這裡把它叫做協議號,個人理解就是根據這個協議號,伺服器端知道去執行什麼邏輯;比如http協議請求行中的/test.html,dubbo協議中的服務名+版本號,redis中的具體要執行什麼key;

這個是否需要還是要看各自的場景,比如redis協議足夠簡單,無需任何標識,所有的東西都是雙端約定好的;但是其他很多協議還是有一些需要的,除了上面說到的可以在訊息頭中指定datalength,其實還有很多其他的東西可以指定比如:

業務資料往往在整個資料報中是最大的,同時也是大小可變的部分;我們上面所做的這些其實都是在為業務資料服務,業務資料需要在網路傳輸,最重要的一點就是序列化,一般就以下兩種方式:

二進位制方式:常見的比如protobuf,thrift,kyro等;

是否需要預留字段這個得看情況,比如http協議整個訊息頭是可變的,每一行乙個標識,知道讀取到空行,表示訊息頭結束下面就是正文了,可以理解為http使用了兩種方式來保證完整包,訊息頭使用特殊字元結尾,正文使用在訊息頭中指定datalength;這種方式其實它的整個擴充套件性是非常好的;另外一種像dubbo這樣,其實它的頭部相當於已經固定好了16個位元組,這種情況下是否可以預留幾個位元組防止後面的變更;

自定義協議其實在我們真正的工作中還是很少能接觸到的,更多的其實還是去實現業務,但是我們系統無時無刻不在和各種應用層協議打交道,如果我們了解了各種協議,在系統出現問題時可以做抓包分析;另外像我們常用的資料庫中介軟體、快取中介軟體等,都需要對協議都充分的了解,然後去實現**。

- end -

往期推薦

rpc框架設計概要

《大廠面試》之線上故障排查

《生產事故》之反射引發的宕機問題

自定義協議 你也可以自定義報頭協議

在學習過計算機網路的課程,我們知道剛開始計算機都是單獨離線工作的,沒有聯網的情況下計算機的資訊共享能力 運算能力都非常有限,後來誕生了計算機網路.有了就是那幾網路,計算機 a 的資訊和資料可以通過網路傳遞到計算機 b,同樣計算機 a 可以獲取到來自計算機 b 的資料.但是不同計算機之間交換資料的時候...

7 自定義異常 如何自定義異常???

自定義異常類時,需要繼承exception類或其子類 一般多繼承自exception或runtimeexception 如果繼承exception,則為檢查異常,必須處理 如果繼承runtimeexception,則為執行時異常,可以不處理 public class test public stat...

自定義協議族

include include include include define pf myfamily 28 static void stream csk destroy sock struct sock sk static void my proto close struct sock sk,lon...