Java ObjectInputStream-StreamCorruptedException:无效类型代码:00
首先,我知道有很多关于这个特例的问题,但似乎没有一个有好的答案 我有一个通过TCP套接字与服务器通信的本地客户端网络。他们正在从服务器接收大量数据。当我开始我的测试时,它在一段时间内运行得相当好,但最终我在其中一个流上看到了这个异常Java ObjectInputStream-StreamCorruptedException:无效类型代码:00,java,serialization,corruption,objectinputstream,Java,Serialization,Corruption,Objectinputstream,首先,我知道有很多关于这个特例的问题,但似乎没有一个有好的答案 我有一个通过TCP套接字与服务器通信的本地客户端网络。他们正在从服务器接收大量数据。当我开始我的测试时,它在一段时间内运行得相当好,但最终我在其中一个流上看到了这个异常 java.io.StreamCorruptedException: invalid type code: 00 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1373)
java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1373)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
at myProgram.connectionProtocol.waitForMsg(connectionProtocol.java:137)
at myProgram.Client.ClientProcess$testController.run(ClientProcess.java:296)
at myProgram.Client.ClientProcess.main(ClientProcess.java:71)
更新:
我已尝试强制每个进程在继续之前等待确认消息,并在遇到此错误时发送重新发送。这增加了更多的复杂性,而且造成的问题似乎比解决的问题还多
我将代码中更新的缓冲流添加到所有输入中,听说这将提高IO性能,但运气不好。不过,这并没有造成问题,所以我将把它留在里面
以下是我删除垃圾后的一些代码:
服务器:
private Socket client;
private String clientName = "?";
private Boolean threadActive = true;
private PublicKey clientKey;
private int timeout = 100;
ClientWorker(Socket sock) {
client = sock;
}
public void run(){
Object line;
ObjectInputStream in = null;
ObjectOutputStream out = null;
client.setSoTimeout(timeout);
in = new ObjectInputStream(new BufferedInputStream(client.getInputStream()));
out = new ObjectOutputStream(new BufferedOutputStream(client.getOutputStream()));
out.flush();
while(threadActive){
Message msgOut = msgQueue.get(0);
if(msgOut != null && msgOut.source.equals(clientName)){
msgQueue.remove(0);
msgOut.source = "broker";
out.writeObject(secure.signObject(msgOut,privKey));
out.flush();
out.reset();
}
try{
line = in.readObject();
handleMessage((SignedObject) line);
} catch(SocketTimeoutException e){
//no data currently in stream
}
}
client.close();
}
客户:
serverSock = new connectionProtocol(name,privKey);
socketNum = serverSock.getSocketNum("server");
serverSock.openSocket(socketNum);
serverSock.setSoTimeout(100);
while(isActive){
// ERROR OCCURS IN NEXT LINE
serverMsg = (SignedObject)serverSock.waitForMsg();
if(serverMsg != null)
handleMessage(brokerMsg);
// messages are sent/received over other sockets here
}
serverSock.closeSocket();
另一个线程也会定期调用serverSock.sendMsgMessage
连接协议:
public void openSocket(int sockNum) throws IOException {
socket = new Socket("localhost", sockNum);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
out.flush();
Message initMessage = new Message(name,"open");
SignedObject sigMessage = security.signObject(initMessage, privKey);
out.writeObject(sigMessage);
out.flush();
out.reset();
socketActive = true;
}
public synchronized void closeSocket(){
socketActive = false;
Message closeMessage = new Message(name,"end");
out.writeObject(security.signObject(closeMessage,privKey));
out.flush();
socket.close();
}
public synchronized Object waitForMsg() throws IOException {
Object msg = null;
try {
// ERROR OCCURS ON NEXT LINE
msg = in.readObject();
return msg;
} catch (SocketTimeoutException e) {
return null;
}catch (ClassNotFoundException e) {
e.printStackTrace();
}
return msg;
}
public synchronized void sendMsg(Message msg){
out.writeObject(security.signObject(msg, privKey));
out.flush();
out.reset();
}
您应该在ObjectInputStream之前而不是之后构造ObjectOutputStream。发布对等代码。读取超时的catch块内发生了什么?对等代码是什么?你是说客户方面?那本该贴出来的,但不知怎么的却丢了。我再试一次。如果有超时,什么也不会发生——这只是意味着流中没有消息,它可以再次循环。那么超时的意义是什么?为什么不干脆封锁呢?我不相信ObjectInputStream写得这么好,以至于它可以在超时后无缝地恢复。如果这个问题只发生在超时之后,那就可以解释了。我添加了一条注释-在同一个循环中,有消息通过其他套接字发送和接收。我只是不想包含所有与此问题无关的代码。每秒会发生多次超时,因此我不能完全排除,但我不怀疑这是问题所在,因为异常是在操作几分钟后发生的。@EJP,您能将以前的评论作为答案发布吗?我试着把监听和发送放在一个单独的线程中,但结果失败了,它似乎成功了