資料封包解包協議之TCP封包解包

2021-08-29 02:13:38 字數 3414 閱讀 7861

資料封包協議規定:整個資料報包含2位元組長度資訊+資料報體。2位元組長度資訊包含本身著2位元組。如:資料體是(abcdefg)7個位元組,整體封包就是09abcdefg,總共是9個位元組的協議

1、netbus接收到資料後傳送到static void on_recv_tcp_data(uv_session* s),資料報含在session管理裡面s->recv_buf和s->recved兩個屬性是這個session收取的資料資訊

static void on_recv_tcp_data(uv_session* s)

if (s->recved < pkg_size)

//至少收到了乙個完整的資料報

unsigned char* raw_data = pkg_data + head_size; //資料報的起始記憶體位址,去掉長度

on_recv_client_cmd((session*)s, raw_data, pkg_size - head_size); //處理資料

if (s->recved > pkg_size)

//recved的資料最少要等於pkg_size,所以recved不可能小於0,如果recved小於pkg_size上邊乙個條件判斷就會中斷了

s->recved -= pkg_size;

if (s->recved == 0 && s->long_pkg != null)

//end

} }

2、pkg_data是因為資料報體可能超過協議長度recv_len,所以會啟用long_pkg,來處理很大的包

下面是乙個死迴圈用來處理接收到的資料(大包處理具體請看這邊文章)

3、read_header函式根據封包協議解析出資料報長度資訊

bool tcp_protocol::read_header(unsigned char* data, int data_len,int* pkg_size, int* out_head_size)

*pkg_size = ((data[0]) | (data[1] << 8));

*out_head_size = 2;

return true;

}

收到乙個完整資料報的情況下(假設收到的資料封包為09abcdefg)

1、read_header

是用來讀取包長度資訊的,因為規定2位元組是長度資訊,所以如果收到的資訊沒有2位元組就沒有辦法解析出長度,所以跳出迴圈繼續接收資料,否則就根據前2位元組解析出pkg_size和

head_size

,head_size永遠為2位元組,這個是規定 2、

if(s->recved < pkg_size)

這時解析出的pkg_size是9,s->recved = 9條件通過往下執行

3、前面判斷通過說明資料接收完成s->recved = 9,raw_data = pkg_data + head_size ,這裡raw_data就是資料報體的記憶體起始位址,因為前2位元組是長度資訊,(09abcdefg)用這個為例,假如從100為第乙個字母位址,那麼資料報的起始位址a就是102,那麼raw_data的起始位址就是102

4、前面判斷都通過,那麼就至少解析到了1整個資料報,就進入

void

on_recv_client_cmd(

session* s

, unsigned

char

* body

, int

len)

函式處理資料

5、處理完成資料後,判斷s->recved > pkg_size除了這個資料報,是否還有其他資料,這裡s->recved = 9,pkg_size = 9,條件不通過,往下執行

6、s->recved -= pkg_size  ,  s->recved = 0;

7、while迴圈條件不成立跳出迴圈

收到1.5個協議包的情況(09abdefg091234)

是用來讀取包長度資訊的,因為規定2位元組是長度資訊,所以如果收到的資訊沒有2位元組就沒有辦法解析出長度,所以跳出迴圈繼續接收資料,否則就根據前2位元組解析出pkg_size和

head_size

,head_size永遠為2位元組,這個是規定

2、if(s

->recved < pkg_size)

這時解析出的pkg_size是9,s->recved = 15條件通過往下執行

3、前面判斷通過說明資料接收完成s->recved = 15,raw_data = pkg_data + head_size ,這裡raw_data就是資料報體的記憶體起始位址,因為前2位元組是長度資訊,(09abcdefg)用這個為例,假如從100為第乙個字母位址,那麼資料報的起始位址a就是102,那麼raw_data的起始位址就是102

4、進入

on_recv_client_cmd

處理資料

5、處理完成資料後,判斷s->recved > pkg_size除了這個資料報,是否還有其他資料,這裡s->recved = 15,pkg_size = 9,條件通過,

下面是目前記憶體分布情況

執行memmove

函式,memmove(pkg_data, pkg_data + pkg_size,

s->recved - pkg_size)

,前面乙個資料封包已經處理好,下次要處理第二個資料封包,

on_recv_ws_data

每次都是從s->recv_buf的起始位置開始處理,所以需要把第二個封包移動到recv_buf的起始為位置,第二個資料報的起始位址是recv_buf的起始位址100 再加上第乙個資料封包的長度9,所以第二個資料封包的起始位址就是recv_buf + pkg_size ,pkg_data就是recv_buf,所以等於pkg_data + pkg_size,移動資料長度是剩下沒有處理的資料的長度s->recved - pkg_size = 15 - 9 = 6,移動6個位元組,這樣就把第二個資料封包移動到s->recv_buf的起始位址

6、s->recved -= pkg_size , s->recved = 6表示還有6個位元組長度沒有處理完成,繼續while迴圈,當執行完成read_header函式後解析出第二個資料封包長度為9,但是剩餘長度只剩下6,還有3位元組沒有接收完成,所以到if(

s->recved < pkg_size)

判斷的時候跳出while迴圈,netbus繼續接收資料

python 基礎筆記5 封包解包使用包

1.建立包結構 subl sublime開啟資料夾 tree 包 的內部結構 setup.py 包啟動檔案 suba aa.py 該檔案包含多個python函式 bb.py init py 必須檔案 subb cc.py dd.py init py setup.py的內容 包的簡介 from dis...

VC 實現ip資料報解包TCP解包HTTP

我們需要監控使用者的網際網路行為,則需要檢測http 如何在網路層擷取http呢,眾所周知,是80號埠 實現如下 cpp view plain copy print?cinitsock thesock void getftp char pdata,dword dwdestip else if str...

網路協議之TCP

為了實現計算機的通訊,我們為計算機定義了一系列的通訊規則,這些規則就是協議.資料格式封裝 傳輸 將複雜的流程分解為幾個功能相對單一的子程序。osi是乙個理想的模型,因此一般網路系統只涉及其中的幾層,很少有系統能夠具有所有的7層,並完全遵循它的規定。在7層模型中,每一層都提供乙個特殊的網路功能。從網路...