java.io.StreamCorruptedException: invalid stream header
I am having a problem with sending two objects (over a socket). I have read in other posts that this could be due to trying to receive incompatible data types but my applications work fine if I send my objects synchronously rather than asynchronously.
I will try my best to describe what my problem is as my code is very long.
I have a server and a client application (2 apps). Multiple clients connect to the server and send their details (as an object) to the server. The server then amends the object (adds some more data) and sends it back to the clients. Both the SendObject and ReceiveObject class are threads and I have created a Listener (within the client) that activates when an object is received (asynchronous communication). The Listener method looks to see if the event is an instance of a particular class and casts is as appropriate (as per below).
publicvoid receivedObject(ReceivedObjectEvent e){
ReceiveObjectThread obj = (ReceiveObjectThread) e.getObject();
if(obj.getObject()instanceof Player){
thePlayer = (Player) obj.getObject();
theTable.setHandData(thePlayer.getHand());
}
if(obj.getObject()instanceof GameData){
gameData = (GameData) obj.getObject();
theTable.setPlayerList(gameData.getOpponents());
}
}
The objects that are passed between applications both implement Serializable.
This all works fine synchronously object passing. However, if I try and spawn two sendObject threads within the server and the corresponding two receive threads within the client and wait for the Listener to activate (asynchronously) I get the following error:
java.io.StreamCorruptedException: invalid stream header: 00057372
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at ReceiveObjectThread.run(ReceiveObjectThread.java:84)
java.io.StreamCorruptedException: invalid stream header: ACED0006
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at ReceiveObjectThread.run(ReceiveObjectThread.java:84)
I am sure that this problem is due to my limited knowledge on socket and data transfer. Therefore any help on this one will be gratefully received.
# 1
You have to either:
(i) create and use the same ObjectInputStream and ObjectOutputStream for the life of the socket at both ends, or
(ii) create and use a new ObjectinputStream and ObjectOutputStream for each new request.
No combination of the above will work, and (ii) has overheads and inconveniences that make it pretty pointless.
The reason is that ObjectOutputStream writes a stream header in its constructor that ObjectInputStream tries to read in its constructor, so the constructor invocations have to match up.
ejpa at 2007-7-28 15:32:42 >

# 2
Hello ejp, your reply is very much appreciated.
If I explain how I have implemented my sockets you may be able to see where I wrong.
When a player connects, the client sends the server a player object. The server receives the player object and passes the socket from which it connected (within the server) to a socket property within the player class. Whenever the server needs to send an object to that client (player), it sends the output stream from the socket property within that player object. ( player.getSocket().getOutputStream() ).
Below is the code from the SendObjectThread class.
/**
* This class allows an object to be passed over a Socket
*
* @author Harold Clements
* @version 1.0.1 12-Jun-2007 (12-Jul-2007)
*/
//http://www.seasite.niu.edu/cs580java/Object_Serialization.html
public class SendObjectThread extends Thread {
private OutputStream out;
private Object obj;
/**
* This constructor allows the user to passes the two parameters for transmitting.
* @param out The data stream that the object is going to be sent to.
* @param obj The object to be sent.
*/
public SendObjectThread(OutputStream out, Object obj) {
this.out = out;
this.obj = obj;
}
/**
* The main thread
*/
public void run() {
try {
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(obj);
objOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client only has one socket which is defined when the client first makes a connection with the server. The getOutputStream() and getInputStream() are used for all communication from the client.
Is this what you described in your first option?
The funny thing about it all is if I create a new receiveObjectTread and wait for that to finish, then create another receiveObjectTread both objects in question (Player and GameData) are received correctly and the application works. I only have the problem when I set both threads off and leave it for the ReceivedObjectEvent listener to pick them up and cast them (as per my first post).
Thanks again for your help,
Harold Clements