iOS網(wǎng)絡(luò)編程TCP/IP應(yīng)用篇(三)-協(xié)議的定制

上面兩篇介紹了庫的接口及封裝,還有個問題就是數(shù)據(jù)的處理。

問題一:怎么處理通過回調(diào)【-(void) onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag】接收的數(shù)據(jù)

tcp協(xié)議面向字節(jié)流,無邊界,有序的。根據(jù)這些特性我們第一步要做的就是劃邊界,交互的數(shù)據(jù)可以都是字符串,在每個結(jié)尾處給一個特殊的字符表示結(jié)束,這樣我們就可以向http一樣傳json了,短鏈接這樣實現(xiàn)是沒問題的,但是如果長連接你還得定義字段說明這塊數(shù)據(jù)的意義,而且會增加流量。在長連接中,我們用結(jié)構(gòu)體來給字節(jié)流劃出邊界,比如:

typedef struct

{

? ? ? unsigned char ? ?Account[32];

? ? ? unsigned char ? Password[32];

}LoginData;//發(fā)給服務(wù)器

typde struct

{

uint16_t isSuccess;//0-失敗 1成功


}LoginRspose;//服務(wù)器處理后的返回

如果我知道一塊數(shù)據(jù)時代碼登錄數(shù)據(jù)的,我可以直接強制轉(zhuǎn)換成這個結(jié)構(gòu)體,然后再進行處理。

問題來了,我們(服務(wù)器端或客戶端)如何知道這塊數(shù)據(jù)是代表登錄數(shù)據(jù)了?在1000個字節(jié)里怎么確定這快數(shù)據(jù)的位子?

有序!這快數(shù)據(jù)絕對是連續(xù)的,我們現(xiàn)在把每一個接收能完整處理的或發(fā)生的一個完整的數(shù)據(jù)集叫一個數(shù)據(jù)包,我們要傳送賬號字符串我們就增加了一個char數(shù)組,現(xiàn)在要知道位字,需要定義個公用包頭來解決以上問題,后面將以包頭來解析數(shù)據(jù)。包頭最基本的應(yīng)該包括:

1,包體大小(根據(jù)這個取出數(shù)據(jù));

2,包體類別(根據(jù)這個判斷包的功能,我們采用命令的方式來編寫代碼,采用一級命令和二級命令);

我們將這個緩沖區(qū)定義成一下結(jié)構(gòu)體

typedef struct

{

TCP_Head Head;//數(shù)據(jù)包頭

unsigned char Buffer[SOCKET_TCP_PACKET];//數(shù)據(jù)緩沖

}TCP_Buffer;

SOCKET_TCP_PACKET宏定義緩沖區(qū)大小減去包頭大小(SOCKET_TCP_BUFFER-sizeof(TCP_Head))。

包頭定義為

typedef struct

{

TCP_infomation ? Info;

TCP_Eventtype type;

}TCP_Head;

包頭里的結(jié)構(gòu)體定義

typedef struct

{

uint8_t ?version;//使用消息的版本號

uint16_t ?datalenth;//包體數(shù)據(jù)長度

}TCP_infomation

根據(jù)datalenth取出數(shù)據(jù)大小

typedef struct

{

uint16_t FistCommond;

uint16_t SecondCommond;

}TCP_type

根據(jù)命令來判斷出這個數(shù)據(jù)包的功能,去執(zhí)行哪一段邏輯代碼

比如我們規(guī)定 F=0,S= 1為登錄命令,把數(shù)據(jù)填充到LoginData中在拷貝到TCP_Buffer結(jié)構(gòu)體中的Buff中,算出包的到大小賦值給datalenth,發(fā)發(fā)送給服務(wù)端,服務(wù)器就可以根據(jù)這些字段來處理。

包頭是服務(wù)端和客戶端都必須嚴格遵守的,不符合這個協(xié)議的數(shù)據(jù)都會被丟棄,當然這個協(xié)議是根據(jù)你項目的需求定制的,比如要加密或帶時間戳都可以在包頭擴展數(shù)據(jù),邏輯協(xié)議就是命令的定義及該命令定對應(yīng)的數(shù)據(jù)結(jié)構(gòu)體,這是分為2份,(命令可能一樣,但是業(yè)務(wù)數(shù)據(jù)結(jié)構(gòu)體可能不一樣)比如:以上登錄命令都可以是0-1,但是客戶端發(fā)送登錄命令必須遵守LoginData協(xié)議,服務(wù)器處理完0-1后返回的數(shù)據(jù)必須遵LoginRspose協(xié)議。以上是比較簡單的,只說出了定義協(xié)議的思路,需要根據(jù)項目的需求定義出可以擴展,安全的協(xié)議。

下一遍我會講怎么根據(jù)協(xié)議解析數(shù)據(jù)(斷包,粘包處理)。這里已經(jīng)有了處理思路,我們定義協(xié)議就是為了處理這些問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容