我有一个不寻常的问题,导致我把头发撕掉了。我有一个Netty客户端/服务器设置。服务器将命令对象发送到客户端。然后,客户端将命令对象中找到的每个二进制命令发送到连接到其本地串行端口的设备。每个命令(二进制字符串)的答案都存储在命令对象中,并且当所有命令都已执行时,命令对象将返回给服务器。所以我在客户端和服务器管道中都使用了ObjectEncoder和ObjectDecoder。
我有一个特定的,可重复的情况,当特定的命令对象返回到服务器时,服务器抛出“java.io.StreamCorruptedException:意外的块数据结束”(下面的堆栈跟踪)。我在服务器和客户端都使用Netty 3.2.7-Final,我在客户端和服务器上都使用Oracle Java 1.7.0_02。
真正做到的是,如果我运行客户端&在Windows 7下本地服务器,然后作业正确运行。如果我在Debian Linux系统上远程运行服务器,则特定作业可以正常运行。但是,当我在Linux CentOS 6系统上运行服务器时,作业会在每个时间内失败并出现异常。 (客户端必须在Windows环境中运行)
任何有关如何进一步调试的建议都将非常受欢迎。我已经看过扩展ObjectEncoder,所以我可以将序列化的对象转储到磁盘上以查看线路上的内容,但是我无法弄清楚如何获取编码方法返回的ChannelBuffer的内容。
java.io.StreamCorruptedException: unexpected end of block data
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1369)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:498)
at java.lang.Throwable.readObject(Throwable.java:913)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at java.util.ArrayList.readObject(ArrayList.java:733)
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at org.jboss.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:129)
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:351)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:282)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:202)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
答案 0 :(得分:1)
由于解码时出现问题,
您可以在解码之前将接收到的通道缓冲区十六进制转储到日志中,然后再进行分析。您必须拥有自己的ObjectDecoder版本,如
@Override
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
ChannelBuffer frame = (ChannelBuffer) super.decode(ctx, channel, buffer);
if (frame == null) {
return null;
}
logger.debug("Hex dump of object frame [" + ChannelBuffers.hexDump(frame) + "]");
return new CompactObjectInputStream(
new ChannelBufferInputStream(frame), classResolver).readObject();
}