Search code examples
javasocketserror-handlingtcpclienttcpserver

java.io.StreamCorruptedException: invalid stream header: 73720019


When random object sent from TCP Server to TCP Client first time everything works fine, but when TCP Server sends again random object this error happens. I have tried with flush() method after sending data, but did not work either. Please, help me...

Sending point of TCP Server

try {
    serverSocket = new ServerSocket(PORT);textArea.append("Server started, port : " + PORT + "\n");
    socket = serverSocket.accept();
    textArea.append("Client connected...\n");

    Object object = randomObject();
    out = new ObjectOutputStream(socket.getOutputStream());
    out.writeObject(object);
    textArea.append("Object sent...\n");
    String message = "";

    while(socket.isConnected()){
        in = new ObjectInputStream(socket.getInputStream());
        message = String.valueOf(in.readObject());
        if(message.equals("Please, send me object again...")){
            textArea.append("Message received : " + message + "\n");
            Object s = randomObject();
            out.writeObject(s);
            textArea.append("Object sent again...\n");
        }
    }

} catch (IOException e) {
    throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
}

Problem is here in TCP Client, line breaks at new ObjectInputStream.

try {
    socket = new Socket(ADDRESS, PORT);
    System.out.println("Connected...");

    speedLbl.setText("Speed : " + speed + "px");

    while(socket.isConnected()){
        inputStream = socket.getInputStream();

        in = new ObjectInputStream(inputStream);
        object = in.readObject();

        if(object instanceof Kvadrat){
            kvadrat = (Kvadrat) object;
            koordinatniSistem.add(kvadrat);
            System.out.println(kvadrat.getName());
            label.setText("X : " + kvadrat.getX() + " - Y: " + kvadrat.getY());
        } else if (object instanceof Pravougaonik) {
            pravougaonik = (Pravougaonik) object;
            koordinatniSistem.add(pravougaonik);
            System.out.println(pravougaonik.getName());
            label.setText("X : " + pravougaonik.getX() + " - Y: " + pravougaonik.getY());
        } else if (object instanceof Krug) {
            krug = (Krug) object;
            koordinatniSistem.add(krug);
            System.out.println(krug.getName());
            label.setText("X : " + krug.getX() + " - Y: " + krug.getY());
        }else if (object instanceof Trougao) {
            trougao = (Trougao) object;
            koordinatniSistem.add(trougao);
            System.out.println(trougao.getName());
            label.setText("X : " + trougao.getX() + " - Y: " + trougao.getY());
        } else {
            System.out.println(object.getClass().getSimpleName());
        }
        koordinatniSistem.repaint();
    }

} catch (IOException | ClassNotFoundException e) {
    throw new RuntimeException(e);
}

Solution

  • You need to create the ObjectInputStream in both client and server once, before the loops. Also, I don't see an ObjectOutputStream in your client code, but if there is (judging by the use of an ObjectInputStream in the server there should be), it should also be created only once.

    The problem is that the object input/output streams have a specific protocol, where the creation of the ObjectOutputStream sends a "stream header", and the ObjectInputStream when created expects to read that header. If you create the object output stream once, but create a new object input stream for each iteration of the loop, then the second creation will fail, because there is no such stream header to read.

    Also, to avoid mutual waiting, make sure to create ObjectOutputStream before ObjectInputStream.