W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
系統(tǒng)設(shè)計(jì),協(xié)議先行。
大部分技術(shù)人沒(méi)有接觸協(xié)議的設(shè)計(jì)細(xì)節(jié),更多的是使用已有協(xié)議進(jìn)行應(yīng)用層的編碼,例如:
(1)使用http作為載體,設(shè)計(jì)get/post/cookie參數(shù)
(2)使用dubbo框架,而不用去深究?jī)?nèi)部的二進(jìn)制包頭包體,以及序列號(hào)反序列化的細(xì)節(jié)
所謂“協(xié)議”是雙方共同遵守的規(guī)則,例如:離婚協(xié)議,停戰(zhàn)協(xié)議。協(xié)議有語(yǔ)法、語(yǔ)義、時(shí)序三要素。
(1)語(yǔ)法:即數(shù)據(jù)與控制信息的結(jié)構(gòu)或格式
(2)語(yǔ)義:即需要發(fā)出何種控制信息,完成何種動(dòng)作以及做出何種響應(yīng)
(3)時(shí)序:即事件實(shí)現(xiàn)順序的詳細(xì)說(shuō)明
應(yīng)用層協(xié)議選型,常見(jiàn)的有三種:文本協(xié)議、二進(jìn)制協(xié)議、流式XML協(xié)議。
(1)文本協(xié)議
文本協(xié)議是指 “貼近人類書(shū)面語(yǔ)言表達(dá)”的通訊傳輸協(xié)議,典型的協(xié)議是http協(xié)議,一個(gè)http協(xié)議大致長(zhǎng)成這樣:
GET / HTTP/1.1
User-Agent: curl
Host: musicml.net
Accept: */*
文本協(xié)議的特點(diǎn)是:
a.可讀性好,便于調(diào)試
b.擴(kuò)展性也好(通過(guò)key:value擴(kuò)展)
c.解析效率一般(一行一行讀入,按照冒號(hào)分割,解析key和value)
d.對(duì)二進(jìn)制的支持不好 ,比如語(yǔ)音/視頻
im中,msn使用的是文本協(xié)議。
(2)二進(jìn)制協(xié)議
二進(jìn)制協(xié)議是指binary協(xié)議,典型是ip協(xié)議,以下是ip協(xié)議的一個(gè)圖示:
二進(jìn)制協(xié)議一般定長(zhǎng)包頭和可擴(kuò)展變長(zhǎng)包體 ,每個(gè)字段固定了含義 ,例如IP協(xié)議的前4個(gè)bit表示協(xié)議版本號(hào) (Version)。
二進(jìn)制協(xié)議有這樣一些特點(diǎn):
a.可讀性差,難于調(diào)試
b.擴(kuò)展性不好 ,如果要擴(kuò)展字段,舊版協(xié)議就不兼容了,所以一般設(shè)計(jì)時(shí)會(huì)有一個(gè)Version字段
c.解析效率超高(幾乎沒(méi)有解析代價(jià))
對(duì)二進(jìn)制的支持不好 ,比如語(yǔ)音/視頻
im中,QQ使用的時(shí)二進(jìn)制協(xié)議。
(3)流式XML協(xié)議
im的準(zhǔn)標(biāo)準(zhǔn)協(xié)議xmpp就是使用流式XML,像gtalk,校內(nèi)通這些im都是基于xmpp的,讓我們來(lái)看一個(gè)xmpp協(xié)議的例子:
<message
to=’romeo@example.net’
from=’juliet@example.com’
type=’chat’
xml : lang=’en’>
<body>Wherefore art thou, Romeo?</body>
</message>
從xml標(biāo)簽中大致可以判斷這是一個(gè)romeo發(fā)給juliet的聊天消息。
xmpp協(xié)議可以實(shí)現(xiàn)跨域的互通。例如gtalk和校內(nèi)通用戶聊天。只要服務(wù)端實(shí)現(xiàn)了s2s服務(wù)(server to server) ,不過(guò)現(xiàn)在的im基本沒(méi)有互通需求 ,所以這個(gè)服務(wù)基本沒(méi)有人實(shí)現(xiàn)。
Xmpp協(xié)議有幾個(gè)特點(diǎn):
a.它是準(zhǔn)標(biāo)準(zhǔn)協(xié)議,可以跨域互通
b.XML的優(yōu)點(diǎn),可讀性好,擴(kuò)展性好
c.解析代價(jià)超高(dom解析)
d.有效數(shù)據(jù)傳輸率超低(大量的標(biāo)簽)
個(gè)人旗幟鮮明的強(qiáng)烈不建議使用xmpp,特別是無(wú)線端im,如果要用,一定要自己做壓縮 ,減少網(wǎng)絡(luò)流量(用過(guò)xmpp的同學(xué)都清楚,發(fā)一個(gè)登錄包需要多少交互,要浪費(fèi)多少流量)。
實(shí)際的栗子
下面來(lái)看一個(gè)im協(xié)議的實(shí)際例子 ,一般常見(jiàn)的做法是:定長(zhǎng)二進(jìn)制包頭,可擴(kuò)展變長(zhǎng)包體。
包體可以使用用文本、XML等擴(kuò)展性好的協(xié)議。
包頭負(fù)責(zé)傳輸和解析效率,與業(yè)務(wù)無(wú)關(guān)。包體保證擴(kuò)展性,與業(yè)務(wù)相關(guān)。
這是一個(gè)實(shí)際的16字節(jié)im二進(jìn)制定長(zhǎng)包頭
//sizeof(cs_header)=16
struct cs_header
{
uint32_t version;
uint32_t magic_num;
uint32_t cmd;
uint32_t len;
uint8_t data[];
}__attribute__((packed));
a.前4個(gè)字節(jié)是version;
b.接下來(lái)的4個(gè)字節(jié)是個(gè)“魔法數(shù)字(magic_num)“,用來(lái)保證數(shù)據(jù)錯(cuò)位或丟包問(wèn)題,常見(jiàn)的做法是,包頭放幾個(gè)約定好的特殊字符,包尾放幾個(gè)約定好的特殊字符 約定好,發(fā)給你的協(xié)議,某幾個(gè)字節(jié)位置,是0x 01020304 ,才是正常報(bào)文;
c.接下來(lái)是command(命令號(hào)),用來(lái)區(qū)分是keepalive報(bào)文、業(yè)務(wù)報(bào)文、密鑰交換報(bào)文等;
d.len(包體長(zhǎng)度),告知服務(wù)端要接收多長(zhǎng)的包體。
這是一個(gè)實(shí)際的可擴(kuò)展im變長(zhǎng)包體
message CUserLoginReq
{
optional string username = 1;
optional string passwd = 2;
}
message CUserLoginResp
{
optional uint64 uid =1;
}
使用的是google的Protobuf協(xié)議,可以看到,登錄請(qǐng)求包傳入的是用戶名與密碼,登錄響應(yīng)包返回的是用戶的uid。
當(dāng)然,除了Protobuf,可選擇的可擴(kuò)展包體協(xié)議還有xml、json、mcpack(這...)等。
個(gè)人旗幟鮮明的推薦使用Protobuf,主要有幾個(gè)原因:
a.現(xiàn)成的解析庫(kù)種類多,可以生成C++、Java、php等代碼
b.自帶壓縮功能
c.在工業(yè)界已廣泛應(yīng)用
d.google制造
im協(xié)議,消息的保密性非常重要 ,誰(shuí)都不希望自己聊天內(nèi)容被看到,所以安全層是必不可少的。
1、SSL
證書(shū)管理微微復(fù)雜,代價(jià)有點(diǎn)高。
2、自行加解密
自己來(lái)搞加解密,核心在于密鑰的生成與管理,密鑰管理方式有多種,主要有這么三種:
(1)固定密鑰
服務(wù)端和客戶端約定好一個(gè)密鑰,同時(shí)約定好一個(gè)加密算法(eg:AES ),每次客戶端im在發(fā)送前,就用約定好的算法,以及約定好的密鑰加密再傳輸,服務(wù)端收到報(bào)文后,用約定好的算法,約定好的密鑰再解密。這種方式,密鑰和算法對(duì)程序員都是透明的。
(2)一人一密鑰
簡(jiǎn)單說(shuō)來(lái)就是每個(gè)人的密鑰是固定的,但是每個(gè)人之間又不同,其實(shí)就是在固定密鑰的算法中包含用戶的某一特殊屬性,比如用戶uid、手機(jī)號(hào)、qq號(hào)等。
(3)動(dòng)態(tài)密鑰(一session一密鑰)
動(dòng)態(tài)密鑰,一Session一密鑰的安全性更高,每次會(huì)話前協(xié)商密鑰。
密鑰協(xié)商的過(guò)程要經(jīng)過(guò)2次非對(duì)稱密鑰的隨機(jī)生成,1次對(duì)稱加密密鑰的隨機(jī)生成,具體詳情這里不展開(kāi),有興趣的同學(xué)可以看下SSL密鑰協(xié)商額過(guò)程。
可選的協(xié)議有TCP和UDP
現(xiàn)在的im傳輸層基本都是使用TCP,有了epoll等技術(shù)后,多連接就不是瓶頸了,單機(jī)幾十萬(wàn)鏈接沒(méi)什么問(wèn)題。
先聊這么多,希望對(duì)大伙進(jìn)行應(yīng)用/安全/傳輸層協(xié)議選型有幫助。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: