2010-10-24 126 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