二進制協議 vs 文本協議
在服務器程序開發過程中,各個服務直接需要進行交互。這樣就需要定義消息的協議,一般來說協議主要包括二進制協議和文本協議,下面就我在工作中用到的兩種協議說說自己的看法。
1 二進制協議
目前在公司做服務器后台開發的工作,需要多個服務程序進行交互。因為是TCP直連,所以直接采用二進制消息的方式。消息的定義統一采用消息頭(消息ID+消息長度)+x消息體(消息內容)的方式,所以擴展是比較方便的。用代碼表示如下
struct CommonMsg
{
uint32_t m_msgId;
uint32_t m_msgLen;
};
struct KeepAlive:public CommonMsg
{
uint32_t m_timeStamp;
};
doRead()
{
CommonMsg * msg=(CommonMsg*)buffer;
if(msg->m_msgId==ID_KEEP_ALIVE)
{
handleKeepAlive(msg);
}
}
1.1 優點
二進制協議有以下幾個優點:
1. 節約內存,帶寬。
二進制協議只保存了必須的信息,在需要傳遞大量信息的時候,對於帶寬的節省是非常明顯的。
2. 方便加密。
二進制協議很方便使用異或 或者壓縮的方式進行加密,防止協議被破解,從而保護了傳遞的信息,增加協議破解的難度。
1.2 缺點
二進制協議的缺點也非常明顯:
1. 難以解析。
對於每一條消息,因為無法自解釋,所以對於每一條消息都必須要有對應的文檔進行說明。文檔和代碼的一致性就顯得很重要了。
2. 不跨處理器。
因為是嚴格的內存到對象的轉換,所以要求發送方與接收方的的機器字節序保持一致,否則無法正確解析。
3. 不方便消息的修改。
對於消息的擴展是比較方便的,不過也只能在消息的后面添加字段,才能做到兼容。如果修改已有字段的順序就會造成消息無法正確解析。
2 文本協議
在http請求中,一般會采用json或者xml形式的協議。特別是對於web端的前后台交互更多的會采用json。
用代碼表示一般如下:
//http://www.chat.com/getuserinfo/
//Request:
{
"user":"1234@qq.com",
"token":"af89da025"
}
//Response
{
"code":0,
"msg":"succeed",
"info":
{
"user":"1234@qq.com",
"name":"test",
"group":"test",
"tel":"18888888"
}
}
2.1
文本協議有以下優點:
1. 擴展方便。
如果需要增加一些條件,直接添加Key和Value就可以了,擴展方便。
2. 方便升級。
如果原有的消息需要升級,可以在回復里直接給出升級后請求的地址和消息格式。
3. 方便跨語言跨平台。
對於消息的發送方和接收方的采用的編程語言沒有嚴格的限制,對於多語言編寫提供了便利。
2.2
文本協議的有以下缺點。
1. 浪費帶寬。
因為文本協議傳遞了太多的不會在處理中實際使用的內容,所以在如果處理的請求的量非常大的話,對於帶寬的浪費很嚴重。
2. 不方便加密。
因為文本協議方便解讀,所以如果不希望跟其他的程序共享通信協議,就最好不要采用文本協議。
3 應用場景
尺有所短,寸有所長。每種協議都有自己適用場景。
- 對於公司內部的服務程序之間進行通信,采用二進制協議好一些。
- 對於需要提供給外部的接口,提供文本格式的協議更好。