摘要:成幀解決接收端如何定位消息的首尾位置的問題。無論信息是編碼成文本多字節二進制數或是兩者結合,應用程序協議必須制定消息的接收者如何確定何時消息已完整接收。發送者先要確定消息的長度,將長度信息寫入一個整數,作為消息的前綴。
framing
成幀(framing):解決接收端如何定位消息的首尾位置的問題。
無論信息是編碼成文本、多字節二進制數、或是兩者結合,應用程序協議必須制定消息的接收者如何確定何時消息已完整接收。
如果是采用DatagramPacket發送,則沒有問題,因為它有一個確定的長度告訴接收者,讓其知道消息的結束位置。
如果是通過TCP傳送,則比較復雜,因為TCP協議中沒有邊界的概念。
變長消息如果一個消息中的所有字段都有固定的長度,同時每個消息又是由固定數量的字段組成的話,消息的長度就能夠確定,接收者就可以簡單地講消息長度對應的字節數讀到一個byte[]緩存區中。
如果消息的長度是可變的,則我們無法事先知道需要讀取多少字節。
如果接收者試圖從套接字中讀取比消息本身更多的字節,將可能發生以下兩種情況之一:
1)如果信道中沒有其他消息,接收者將阻塞等待,同時無法處理接收到的消息,如果發送者也在等待接收端的響應信息,則會造成死鎖
2)如果信道中還有其他消息,則接收者會將后面消息的一部分甚至全部讀到第一條消息中去,這將產生一些協議錯誤。
主要有兩個技術使接收者能夠準確地找到消息的結束位置:
1)基于定界符(Delimiter-based)消息的結束由一個唯一的標記指出,即發送者在傳輸完數據后顯式添加的一個特殊字符序列。這個特殊標記不能在傳輸的數據中出現。特殊情況是,可以用在TCP連接上傳輸的最后一個消息上,發送完這個消息后,發送者就簡單地關閉發送端的TCP連接,接收者讀取完這條消息的最后一個字節后,將接收到熬一個流結束標記,即read返回-1,該標記指出已經讀取到達了消息的末尾。
通常用在以文本方式編碼的消息中,定義一個特殊的字符或字符串來標識消息的結束。
public byte[] nextMsg() throws IOException { ByteArrayOutputStream messageBuffer = new ByteArrayOutputStream(); int nextByte; // fetch bytes until find delimiter while ((nextByte = in.read()) != DELIMITER) { if (nextByte == -1) { // end of stream? if (messageBuffer.size() == 0) { // if no byte read return null; } else { // if bytes followed by end of stream: framing error throw new EOFException("Non-empty message without delimiter"); } } messageBuffer.write(nextByte); // write byte to buffer } return messageBuffer.toByteArray(); }2)顯示長度(Explicit length)
在變長字段或消息前附加一個固定大小的字段,用來指定字段或消息中包含了多少字節。發送者先要確定消息的長度,將長度信息寫入一個整數,作為消息的前綴。消息的長度上限定義了用來編碼消息長度所需要的字節數,如果消息的長度小于256字節,則需要1個字節,如果消息的長度小于65536字節,則需要2個字節。
public byte[] nextMsg() throws IOException { int length; try { length = in.readUnsignedShort(); // read 2 bytes } catch (EOFException e) { // no (or 1 byte) message return null; } // 0 <= length <= 65535 byte[] msg = new byte[length]; in.readFully(msg); // if exception, it"s a framing error. return msg; }
readFully方法將阻塞等待,直到給定的數組完全填滿。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65916.html
摘要:基本消息對象的設計消息對象的設計主要由兩部分組成特定數據幀對應的特定消息對象。該類包含上節數據幀主幀及子幀的所有公共信息,僅僅未包含子幀中的數據體信息,該需求由基本消息對象的子類實現。 開發工程中,有一個常見的需求:服務端程序和多個客戶端程序通過 TCP 協議進行通信,通信雙方需通信的消息種類眾多,并且客戶端的數量可能有數萬個。為此,雙方需要約定盡可能豐富、靈活的數據幀「數據包」協議,...
摘要:正則表達式作為一個匹配的模板,是由定界符,原子普通字符,例如有特殊功能的字符稱為元字符,例如等以及模式修正符等部分組成的文字模式。正則表達式中可以使用編碼。限定符限定符用來指定正則表達式的一個給定原子必須要出現多少次才能滿足匹配。 正則表達式的定義 正則表達式就是描述字符排列模式的一種自定義的語法規則。由于正則表達式本身具有一套非常完整的、可以編寫模式的語法體系,提供了一種靈活且直觀的...
摘要:的構造器經過重載可以接受多種輸出目的地,不過最常用的還是和。組號為表示整個表達式,組號表示被第一對括號括起的組,依此類推。有多個重載的構造器,可以接受和對象。 點擊進入我的博客 字符串操作是計算機程序設計中最常見的行為 13.1 不可變String String底層是由char[]實現的,是不可變的。看起來會改變String的方法,實際上都是創建了一個新的String對象,任何指向它...
閱讀 2571·2021-11-22 09:34
閱讀 932·2021-11-19 11:34
閱讀 2801·2021-10-14 09:42
閱讀 1472·2021-09-22 15:27
閱讀 2385·2021-09-07 09:59
閱讀 1731·2021-08-27 13:13
閱讀 3432·2019-08-30 11:21
閱讀 771·2019-08-29 18:35