2010-10-24 127 views
9

我一直在閱讀一些Java套接字代碼片斷,並且發現了一個事實,即在套接字通信中,要按順序發送消息,您不必手動將它們分開,作家/讀者流自動爲你做這些事情。這裏是一個例子:java socket writeUTF()and readUTF()

writer.java 
writeUTF("Hello"); 
writeUTF("World"); 


reader.java 
String a=readUTF(); // a=Hello 
String a=readUTF(); // b=World 

我試過這段代碼,它工作正常。但是,我想知道這種編碼風格是否應該工作正常。沒有明確區分每個段的順序使用套接字流是否存在潛在的風險?

+0

什麼你說「每段明確分開」意思? TCP甚至沒有辦法做到這一點,假設你正在根據RFC討論真正的TCP段。請澄清你的問題。 – EJP 2010-10-25 11:22:50

+0

好吧,我通常會追加一些特殊字符,如「###」並在讀者端檢測它們。這很傻,但我沒有別的辦法。 – 2010-10-26 05:35:08

回答

1

根據文檔readUTFwriteUTF方法使用UTF8的修改版本,該版本還添加了在beginnig中要讀取的字符的長度。

這應該意味着讀取操作將等待,直到返回字符串之前已經獲取了足夠的字符。這意味着如果您沒有看到它,實際上它們也會被分割,因爲您只是用裝飾的套接字流DataInputStreamDataOutputStream

總之,是的,它應該是相當安全的,因爲API本身將負責分離單個消息。

24

writeUTF()readUTF()寫入字符串的長度(以字節爲單位,當編碼爲UTF-8時)後跟數據,並使用modified UTF-8編碼。因此,有一些潛在的問題:

  • 可以這種方式處理字符串的最大長度爲65535純ASCII,少如果使用非ASCII字符 - 你不能輕易預測的極限在這種情況下,除了保守地假設每個字符3個字節。所以如果你確定你永遠不會發送超過20K的字符串,你會沒事的。
  • 如果應用程序需要與別的東西進行通信(這不是用Java編寫的),另一方可能很難處理修改後的UTF-8。對於應用程序內部的溝通,你不必擔心。
+0

非常令人印象深刻的答案,非常感謝。 – 2010-10-26 05:33:11

0

java.net.Socket工作正常,流等待readUTF();

但在使用時,米娜的CumulativeProtocolDecoder,它不會,拋出java.io.EOFException

+1

我嚴重懷疑這種說法是否正確。當對端關閉連接時拋出EOFException。讀取的數據仍然不完整,預計會拋出一個'SocketTimeoutException'。 – EJP 2012-06-05 08:04:55