自己開發了一**票智慧型分析軟體,功能很強大,需要的點選下面的鏈結獲取:
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...