對通訊不熟悉 ,最近在寫這塊,用socket 遇到了點問題。
就是在接收設備端資料時,我打算用 recv函式 可是我的包長度不定,而且有的可能很長 ,還要分包才行,請問我該怎么實作。
最好是一個一個位元組的接收。
我接收的包也有個規律 遇到02 開始接收 遇到03 證明包結束。
請各位指導!!小女子感激不盡。
uj5u.com熱心網友回復:
一般發包方先發一位元組,說明接下來內容有多長!uj5u.com熱心網友回復:
用不住一個一個位元組接受吧,你可以定義一個通訊協議,有你專門資料開始的包頭,比如兩個位元組0x01 0xac ,然后可以跟上這包資料的型別標志,比如0x01 代表A的屬性 0x02 代表B的屬性 再加這包資料的長度,也可以用兩個位元組比如255 0x00 0xff 再跟上資料位元組 最后保險起見可以加CRC校驗,保證資料不錯。整個命令位元組就是 01 ac 01 00 ff + 資料 + CRC 這樣就不會錯了,也不用一個一個接收,可以按一整包接收。 一般上位機和下位機都是按類似協議通訊。
部分接收代碼:
var
leng:longword;
rbuf:array of byte;
begin
leng:=Socket.ReceiveLength;
setlength(rbuf,leng);
for i:=low(rbuf) to high(rbuf) do
begin
rbuf[i]:=0
end;
Socket.ReceiveBuf(rbuf[0],leng);
uj5u.com熱心網友回復:
就是分包,如果不定長,可以在資料前加4個位元組來存盤發送的資料長度,接收時,先去讀前4個位元組,獲得長度,然后根據這個長度去接受后面的資料uj5u.com熱心網友回復:
不定長度的包如果可能很長應該在前面設定一個包長度資料。uj5u.com熱心網友回復:
設備回傳的資料包是有個協議的,我覺得您說的這個應該是比較貼近我的現實情況的。一整個包接收,我用recv函式可以嗎,哪里不是要確定長度才行嗎?能否再詳細指導下,我在這塊確實太菜了
uj5u.com熱心網友回復:
leng:=Socket.ReceiveLength; 這個怎么取?不會uj5u.com熱心網友回復:
LZ協議描述不夠詳細, 不過版主的話可以解決你的問題
uj5u.com熱心網友回復:
我做TCP通訊一般用的是自帶的ClientSocket和ServerSocket,ClientSocket里面有個OnRead事件
procedure TMainForm.ClientSocketRead(Sender: TObject;Socket: TCustomWinSocket);
資料接收觸發。Socket.ReceiveLength是觸發后獲取到的資料包長度。
你說的recv我不知道是哪個里面來的。
uj5u.com熱心網友回復:
原來是這樣,我沒有用控制元件,直接建立的套子段
uj5u.com熱心網友回復:
就是分包,如果不定長,可以在資料前加4個位元組來存盤發送的資料長度,接收時,先去讀前4個位元組,獲得長度,然后根據這個長度去接受后面的資料
LZ協議描述不夠詳細, 不過版主的話可以解決你的問題
這個之前也有人說過,可是看了我的協議覺得不現實。。。。
以下是我的協議
應答幀結構:
+--------+--------+------------------------------------------+
| 欄位 | 位元組數 | 描述 |
+--------+--------+------------------------------------------+
| 幀頭 | 1 | 0x02,表明一幀的開始,為接收方提供同步 |
| 地址 | 2 | 可變資訊標志地址,由可變資訊標志廠家設定 |
| 幀資料 | 不定長 | |
| 幀校驗 | 2 | 供接收方判斷所收幀的正確性 |
| 幀尾 | 1 | 0x03,表明一幀的結束,為接收方提供同步 |
+--------+--------+------------------------------------------+
uj5u.com熱心網友回復:
0x03,表明一幀的結束?那幀資料里出現了0x03怎么辦?
uj5u.com熱心網友回復:
資料里出現結束標識時應當轉義后傳輸0x03,表明一幀的結束?
那幀資料里出現了0x03怎么辦?
uj5u.com熱心網友回復:
自定義一個包結構,包含內容長度和資料就行!uj5u.com熱心網友回復:
實在不會給點案例。。。。uj5u.com熱心網友回復:
一個一個接收沒有任何問題,除非樓主的設備太多。uj5u.com熱心網友回復:
leng:=Socket.ReceiveLength; 這個怎么取?不會
所以你定義協議的時候幀頭(長度固定,且有幀頭標識,帳ID號,連續的傳輸到達順序可能不一樣,方便接收完成后組包然后決議)要包含資料體長度,用來告訴下一幀資料需要讀取的長度是多少,讀完資料體之后,結束幀(長度固定,且有結束幀標識),包含的資訊一般要有校驗位
uj5u.com熱心網友回復:
資料里出現結束標識時應當轉義后傳輸
0x03,表明一幀的結束?
那幀資料里出現了0x03怎么辦?
二進制的協議里,采用轉義是很少見的,因為會造成內容長度的不確定
uj5u.com熱心網友回復:
資料包最大長度應該是有限制的,然后就不停的接收,放到本地快取,另一個執行緒查找包頭和包尾,有滿足的就進行決議拆包。回圈不斷……轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/123410.html
下一篇:delphi 需求如下:查詢各個表中的資料列的資料型別,除int外,所有資料都要通過加密代碼加密,代碼寫到如何讀取型別所對應的列值時
