Socket TCP協議通訊粘包演算法

2022-02-23 16:44:23 字數 3469 閱讀 8407

自己開發了一**票智慧型分析軟體,功能很強大,需要的點選下面的鏈結獲取:

1.問題描述

socket通訊tcp協議雖然是穩定的通訊,但是也會出現丟包的現象,而且會出現乙個資料報分幾次傳送的情況。所以需要用乙個緩衝區去快取資料,並且判斷是不是乙個完整的包。等接收到乙個完整的資料報,然後再去處理解析。

2.解決方案

先要定乙個特殊字串,比如@!,這樣四個位元組的協議頭,在你的通訊報文中絕對不會出現。然後在丟包之後,通過查詢這四個位元組的協議頭,找到包開始的地方,將資料缺失的包過濾掉。找到這個協議頭之後再去解析資料的長度,解析完資料資料長度,在快取這個長度的包資料進行解析。一般是xml、json等格式的字串位元組流。只要讀取指定長度的資料,進行資料解析即可。

3具體實現**

結構定義

#define max_buffer_length        (10*1024)

#define protocol_head_len 12 //

fad 報文頭長度

typedef

struct

buffer_info;

buffer_info m_strecvbuf;

//一次接收資料的快取區

char m_pdatabuff[max_buffer_length];//

每次接收的資料都放入這個緩衝區,空間更加,不斷的處理接收

hpr_int32 m_idatalen;//

總的資料長度

hpr_int32 m_ionefamelen;//

乙個資料報的資料長度,包括協議頭、包長度和包資料

函式演算法實現

hpr_int32 ccuitem::parsedata(hpr_ulong numberofbytes)

log_info(

"receive the data length is %d

",numberofbytes);

int nonefamelen=0

;

if (numberofbytes > 0)//

資料大於0

else

while (m_idatalen>=headerlenth)//

資料長度大於協議頭長度

m_ionefamelen= headerlenth +msglen;//

得到協議頭和包資料的長度

log_info("

one frame length is %d

",m_ionefamelen);

if (m_pdatabuff[0]!='

h'||m_pdatabuff[1]!='

k'||m_pdatabuff[2]!='

p'||m_pdatabuff[3]!='

&')//

判斷協議頭

if (m_pdatabuff[i+1]=='k'

)

if (m_pdatabuff[i+2]=='p'

)

if (m_pdatabuff[i + 3] == '&'

) }}

}}//將databuff向前移動i位

memmove(m_pdatabuff, m_pdatabuff + i, m_idatalen - i);//

刪除前面i個髒資料

m_idatalen = m_idatalen - i;//

重新計算緩衝區資料長度

hpr_zeromemory(m_pdatabuff+ m_idatalen,max_buffer_length- m_idatalen);//

將緩衝區後面的資料置零

m_ionefamelen=0

; log_error(

"pro is wrong!\n");

}else

//頭部是協議頭,處理資料

else

}}

}return

hpr_ok;

}

hpr_int32 ccuitem::parsedata(hpr_ulong numberofbytes)

log_info(

"receive the data length is %d

",numberofbytes);

int nonefamelen=0

;

if (numberofbytes > 0)//

資料大於0

else

while (m_idatalen>=headerlenth)//

資料長度大於協議頭長度

m_ionefamelen= headerlenth +msglen;//

得到協議頭和包資料的長度

log_info("

one frame length is %d

",m_ionefamelen);

if (m_pdatabuff[0]!='

h'||m_pdatabuff[1]!='

k'||m_pdatabuff[2]!='

p'||m_pdatabuff[3]!='

&')//

判斷協議頭

if (m_pdatabuff[i+1]=='k'

)

if (m_pdatabuff[i+2]=='p'

)

if (m_pdatabuff[i + 3] == '&'

) }}

}}//將databuff向前移動i位

memmove(m_pdatabuff, m_pdatabuff + i, m_idatalen - i);//

刪除前面i個髒資料

m_idatalen = m_idatalen - i;//

重新計算緩衝區資料長度

hpr_zeromemory(m_pdatabuff+ m_idatalen,max_buffer_length- m_idatalen);//

將緩衝區後面的資料置零

m_ionefamelen=0

; log_error(

"pro is wrong!\n");

}else

//頭部是協議頭,處理資料

else

}}

}return

hpr_ok;

}

非同步socket TCP 通訊

使用 wsaasyncselect 可實現非同步 socket 通訊,原型 wsaasyncselect socket s,套接字 hwnd hwnd,接收網路事件的視窗控制代碼 unsigned int wmsg,網路事件通知訊息 long lwvent 套接字需要的通知碼 long lwvent...

TCP協議中粘包現象

在tcp協議網路傳輸中,才會出現粘包,udp協議不會出現.tcp的協議資料不會丟,沒有收完包,會繼續上次繼續接收,總是在收到ack時才會清除緩衝區內容。資料是可靠的,但是就會粘包。因為資料傳送和接收過程先經過緩衝區,由於資料大小以及網路原因,導致收發資訊不能嚴格同步,造成資料粘連的現象叫做粘包 粘包...

Luat實現socket tcp通訊

以下 需要在luat通訊模組中使用 建立連線後無法主動關閉,只能靠斷網關閉或者伺服器端關閉 模組功能 tcp連線,報文收發 需要使用合宙官方lib 作者 wangjiaw 983893384 qq.com 版本 20210309 修改記錄1 20210309 require socket modul...