資料幀及訊息定界

2021-09-19 09:39:20 字數 1405 閱讀 7933

成幀(framing):解決接收端如何定位訊息的首尾位置的問題。

無論資訊是編碼成文字、多位元組二進位制數、或是兩者結合,應用程式協議必須制定訊息的接收者如何確定何時訊息已完整接收。

如果是採用datagrampacket傳送,則沒有問題,因為它有乙個確定的長度告訴接收者,讓其知道訊息的結束位置。

如果是通過tcp傳送,則比較複雜,因為tcp協議中沒有邊界的概念。

如果乙個訊息中的所有欄位都有固定的長度,同時每個訊息又是由固定數量的字段組成的話,訊息的長度就能夠確定,接收者就可以簡單地講訊息長度對應的位元組數讀到乙個byte快取區中。

如果訊息的長度是可變的,則我們無法事先知道需要讀取多少位元組。

如果接收者試圖從套接字中讀取比訊息本身更多的位元組,將可能發生以下兩種情況之一:

1)如果通道中沒有其他訊息,接收者將阻塞等待,同時無法處理接收到的訊息,如果傳送者也在等待接收端的響應資訊,則會造成死鎖

2)如果通道中還有其他訊息,則接收者會將後面訊息的一部分甚至全部讀到第一條訊息中去,這將產生一些協議錯誤。

主要有兩個技術使接收者能夠準確地找到訊息的結束位置:

訊息的結束由乙個唯一的標記指出,即傳送者在傳輸完資料後顯式新增的乙個特殊字串行。這個特殊標記不能在傳輸的資料**現。特殊情況是,可以用在tcp連線上傳輸的最後乙個訊息上,傳送完這個訊息後,傳送者就簡單地關閉傳送端的tcp連線,接收者讀取完這條訊息的最後乙個位元組後,將接收到熬乙個流結束標記,即read返回-1,該標記指出已經讀取到達了訊息的末尾。

通常用在以文字方式編碼的訊息中,定義乙個特殊的字元或字串來標識訊息的結束。

public byte nextmsg() throws ioexception  else 

}messagebuffer.write(nextbyte); // write byte to buffer

}return messagebuffer.tobytearray();

}

在變長字段或訊息前附加乙個固定大小的字段,用來指定欄位或訊息中包含了多少位元組。傳送者先要確定訊息的長度,將長度資訊寫入乙個整數,作為訊息的字首。訊息的長度上限定義了用來編碼訊息長度所需要的位元組數,如果訊息的長度小於256位元組,則需要1個位元組,如果訊息的長度小於65536位元組,則需要2個位元組。

public byte nextmsg() throws ioexception  catch (eofexception e) 

// 0 <= length <= 65535

byte msg = new byte[length];

in.readfully(msg); // if exception, it's a framing error.

return msg;

}

readfully方法將阻塞等待,直到給定的陣列完全填滿。

HEVC I幀 P幀及B幀

i和idr幀都是使用幀內 的。它們都是同乙個東西而已,在編碼和解碼中為了方便,要首個i幀和其他i幀區別開,所以才把第乙個首個i幀叫idr,這樣就方便控制編碼和解碼流程。idr幀的作用是立刻重新整理,使錯誤不致傳播,從idr幀開始,重新算乙個新的序列開始編碼。而i幀不具有隨機訪問的能力,這個功能是由i...

python資料幀 Python資料幀

我有乙個dataframe df 並試圖將資料附加到特定的行 index fruit rank 0 banana 1 2 mango 3 3 melon 4 目標是將排名1的水果與每個等級進行比較,然後附加值。我在用difflib.sequencematcher做比較。現在我可以追加到df,但最後我...

MAC幀型別 資料幀

主要有如下幾種型別幀 管理幀 management frame 控制幀 control frame 資料幀 data frame 資料幀mac頭如下 其中address欄位由to ds from ds位來決定 資料幀 to ds 與from ds ds distribution system 分布式...