您好,我正在开发一个使用Netty的服务器。目标是能够来回发送对象。所以我使用ObjectDecoderInputStream和ObjectEncoderOutputStream配置服务器。
所以我有一个客户端也使用Netty与服务器通信。客户运作良好。
每当我使用Java的套接字从服务器接收Serializable对象时。发生了一些奇怪的事情,我在下面有一个例外:
java.io.StreamCorruptedException: Unsupported version: 0
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.readStreamHeader(CompactObjectInputStream.java:38)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.<init>(CompactObjectInputStream.java:30)
at org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream.readObject(ObjectDecoderInputStream.java:115)
at com.bvd.main.Client.readResponse(Client.java:139)
at com.bvd.main.Client.getFile(Client.java:80)
at com.bvd.main.Client.main(Client.java:163)
从客户端发送对象:
public static void writeRequest(Message requestMsg,
OutputStream outputStream) {
byte[] bytes = null;
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
try {
ObjectEncoderOutputStream objectOutputStream = new ObjectEncoderOutputStream(
byteOutputStream, 8192);
objectOutputStream.writeObject(requestMsg);
objectOutputStream.flush();
bytes = byteOutputStream.toByteArray();
byteOutputStream.close();
objectOutputStream.close();
outputStream.write(bytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
以及客户端收到对象的代码:
public static Object readResponse(InputStream inputStream) {
int count = 0;
Object object = null;
try {
byte[] lenBuffer = new byte[4];
while ((count = inputStream.read(lenBuffer)) < 4) {
}
System.out.println(ByteBuffer.wrap(lenBuffer).getInt());
int infolen = ByteBuffer.wrap(lenBuffer).getInt();
byte[] objBuffer = new byte[infolen];
while ((count = inputStream.read(objBuffer)) < infolen) {
}
byte[] totalBuf = new byte[4 + infolen];
System.arraycopy(lenBuffer, 0, totalBuf, 0, lenBuffer.length);
System.arraycopy(objBuffer, 0, totalBuf, lenBuffer.length,
objBuffer.length);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
totalBuf);
System.out.println(byteArrayInputStream.available());
ObjectDecoderInputStream objectDecoderInputStream = new ObjectDecoderInputStream(
new BufferedInputStream(byteArrayInputStream));
object = objectDecoderInputStream.readObject();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object;
}
让我感到困惑的是,当我在2858(字节)的服务器上设置要发送的对象内容的长度(该对象携带已转换为byte []的文件的一部分)时,上面的客户端运行良好;当我将长度改为2859或更大时, StreamCorruptedException 会在上面发生。
ps:发送对象运行良好,服务器成功接收并正确解码,所有问题都是关于从服务器接收的对象。
对不起我的英语不好,任何帮助表示赞赏。感谢。
答案 0 :(得分:0)
while ((count = inputStream.read(lenBuffer)) < 4) {
}
while ((count = inputStream.read(objBuffer)) < infolen) {
}
每次调用read时,它都会将写入byte[]
的开头。所以每次循环时,你都会覆盖缓冲区中的部分数据,不读取整个缓冲区的数据。您需要跟踪当前偏移量(基于您目前已读取的数据量)并将其传递给线程read()
调用。此外,你应该积累计数,而不是分配。