寫網路程式躲不過協議,協議其實就是定義了訊息的格式,以及訊息是如何交換的。協議可簡單可複雜,複雜精密如tcp協議,簡單奔放如http的協議。這裡將我所接觸到的協議稍微總結一下,最後丟擲乙個個人設計的簡單通用的文字協議。
設計乙個協議不是一件很容易的事情,尤其是當對設計的要求包含很好的描述性和可擴充套件性的時候。如果再將效率考慮在內,則更是件耗腦力的活。在繼續討論下去之前,先看看現有的一些協議吧。這裡主要討論的是應用層的協議,應用層的協議大多是請求響應模式(除了zeromq這個**的傢伙,後面再說),所以這裡側重討論訊息格式。
http協議
這可能是大家接觸得最多的協議了,http協議是乙個比較簡單的基於文字的協議。訊息格式基於文字,換行分隔鍵值串,鍵和值用冒號分隔,同時定義了一些標準的鍵和值。這個協議描述性教強——人類可讀。擴充套件性強——加自定義的頭很容易,也幾乎不會有***(除了訊息體積增加一點點)。但是,缺點就是標準定義的東西太多了,細節太多。解析較複雜。
memcached協議
memcached有兩種協議,文字協議和二進位制協議,文字協議以換行表示乙個請求結束。請求內部引數以空格分隔。為了二進位制安全,在二進位制資料前要加上長度這個引數,如set x 3 abc\r\n。
文字協議固然簡單,可是當請求很小的時候,過多的協議本身的資料則顯得浪費(比如每個http請求只傳送乙個字母,可http頭可能有上百的字元,太浪費了),而且,server在接收到請求之後還要做文字解析,也耗cpu,於是memcached又推出了二進位制協議,為了錦上添花,是的memcached更加高效。二進位制協議的優點就是高效,因為所有資訊都以最少的資料量來表達,且server解析請求時做的是數學比較而不是字串比較,效率高很多。
memcached的協議比起http來就輕得多了(當然,兩者所面向的場景不一樣,故這個比較沒太大意義)。但是,也有缺點,就是擴充套件性較差,協議定得比較死,哪個位置上有哪些東西,是什麼意義是定死的。所以,直接哪來用在不同的場景下不大現實。
redis協議
redis的協議也是文字協議,但是設計得比較小心和通用(我後面自己定義的協議深受其影響),在保證描述性的同時儘量減少協議本身的資料量,比如,在memcached的文字協議中,錯誤用「error\r\n」來表示,而redis使用「-」來表示,用「:」開頭的行表示整數等等。這樣的設計結合了文字協議的簡單和一部分二進位制協議的高效。用在redis這個場合,很是適合。交換方式同樣是請求響應。redis協議有乙個缺點,就是,乙個訊息有多少引數是需要在開頭指定的。不像http協議用空行來表示結束。這就帶來乙個缺點,不好流水操作,也就是說訊息必須在傳送第乙個位元組之前被完全確定,因為第乙個東西就是引數個數:-(。
上面討論的基本都是文字協議,當然還有很多採用二進位制協議的服務,如gearman、mysql等,二進位制協議就相當於壓縮版的文字協議,提高了傳輸效率,但是降低了描述性和靈活性(萬一那個位置預留的位數不夠就囧了)。
總的來說,這就是乙個平衡的過程。如果訊息體不是很小(比如每次只傳乙個位元組的訊息就很小了),那麼採用文字協議還是值得的。畢竟文字協議簡單,好擴充套件,利於除錯(telnet就可以當客戶端用),雖說訊息是讓計算機讀的,但有時候也要人去看。所以,能用文字還是用文字吧。
簡單文字協議
最後我定義了乙個簡單的基於文字的協議,叫做******tp(****** text based protocol),詳細定義在這裡這個協議是為了簡單的rpc而設計,結合了http協議的靈活(以空行結束),redis協議的輕量(size+data)。但為了簡單通用,沒有採用redis的單字元表示型別的設計,因為這樣就會引入額外的複雜性,如表示整數用「:」,那麼浮點數、複數等等怎麼辦,乾脆什麼型別都沒有,就簡單的傳輸size+data串(有點類似zeromq,但是比zeromq做的事情少),而具體的型別則交由其他機制去處理,如protocol buffer。
文字協議與二進位制協議的選擇
進行網路通訊時,我們經常糾結於到底使用什麼樣的協議傳輸資料,下面我談談應該怎麼選擇一種合理的協議格式。標準定義是這樣的 為計算機網路中進行資料交換而建立的規則 標準或約定的集合。網路協議至少包括三要素 語法 語法是使用者資料與控制資訊的結構與格式,以及資料出現的順序。語義 解釋控制資訊每個部分的意義...
網路協議 二進位制與文字
進行網路通訊時,我們經常糾結於到底使用什麼樣的協議傳輸資料,下面我談談應該怎麼選擇一種合理的協議格式。標準定義是這樣的 為計算機網路中進行資料交換而建立的規則 標準或約定的集合。網路協議至少包括三要素 語法 語法是使用者資料與控制資訊的結構與格式,以及資料出現的順序。語義 解釋控制資訊每個部分的意義...
IOCP 二進位制協議 分包
一 iocp 二進位制協議分包的思路 解析資料頭,獲取協議包體的大小,判斷是否收到乙個完整的資料頭,如果不是,繼續投遞recv請求,直到收到乙個資料頭 異常的資料報,關閉session pkg size max pkg size 全部資料收到,進行處理.1 判斷long pkg是否存在,如果存在,就...