Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ObjectInputStream-StreamCorruptedException:无效类型代码:00_Java_Serialization_Corruption_Objectinputstream - Fatal编程技术网

Java ObjectInputStream-StreamCorruptedException:无效类型代码:00

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)

首先,我知道有很多关于这个特例的问题,但似乎没有一个有好的答案

我有一个通过TCP套接字与服务器通信的本地客户端网络。他们正在从服务器接收大量数据。当我开始我的测试时,它在一段时间内运行得相当好,但最终我在其中一个流上看到了这个异常

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,您能将以前的评论作为答案发布吗?我试着把监听和发送放在一个单独的线程中,但结果失败了,它似乎成功了