2012-07-23 27 views
2

我想先读取指定消息大小的4个字节(int),然后根据字节数读取其余字节。我使用下面的代码来实现:Java TCP Socket接收指定长度的字节

DataInputStream dis = new DataInputStream(
         mClientSocket.getInputStream()); 

// read the message length 
int len = dis.readInt(); 

Log.i(TAG, "Reading bytes of length:" + len); 

// read the message data 
byte[] data = new byte[len]; 
if (len > 0) { 
    dis.readFully(data); 
} else { 
    return ""; 
} 
return new String(data); 

是否有这样做的更好的/有效的方式?

+2

假设您正在使用阻塞I/O,我认为它非常高效,尤其是如果您必须与非Java代码交互时。这里唯一的气味就是调用一个String类型的构造函数而不指定正确的编码。 – 2012-07-23 19:25:04

回答

2

从的readUTF的JavaDocs

首先,两个字节被读取并用于构建一个无符号16位 * 整数 *与readUnsignedShort方法完全相同。此 整数值称为UTF长度并指定 要读取的附加字节的数量。这些字节然后通过分组考虑将它们转换为 个字符。每个组的长度为 ,根据组的第一个字节的值计算得出。跟在一个组之后的字节 (如果有的话)是下一个组的第一个字节。

唯一的问题是你的协议似乎只发送4个字节的有效载荷长度。也许你可以做一个类似的方法,但是将读取的长度增加到4字节/ 32位。

此外,我看到你只是在做新的字符串(字节),只要数据的编码与“平台的默认字符集”相同,它就可以正常工作。请参阅javadoc因此,确保正确编码它会更安全(例如,如果您知道发件人将其作为UTF-8发送,然后执行新的String(字节,“UTF-8”))。

0

如何

DataInputStream dis = new DataInputStream(new BufferedInputStream(
        mClientSocket.getInputStream())); 

return dis.readUTF(); 
+0

感谢您的建议。我需要读取指定的字节数。不是整个消息。 dis.readUTF()会读取流中的所有内容吗? – ssk 2012-07-23 19:16:10

+0

它用'writeUTF()' – 2012-07-23 19:20:48

-1

您可以使用read(byte[] b, int off, int len)这样

byte[] data = new byte[len]; 
dis.read(data,0,len); 
+0

-1来读取您写入的字节数。并获得缓冲区的部分读取。 – 2012-07-23 19:22:12