So basically im writing a client-server multiplayer game. I have a SeverCommunicationThread that creates a gameThread if he receives a RequestForGame creates a gameThread. When i send a RequestForGame exception is thrown java.io.StreamCorruptedException: invalid type code: 00 I assume it's because both threads try to read the same ObjectInputStream, I don't have much understanding about how it works, i just know how to use it. Could you help me understand what's the problem and how to fix it? Thanks :)
public class ServerCommunicationThread extends Thread{
private Socket connectionSocket;
private ObjectInputStream inFromClient;
private ObjectOutputStream outToClient;
private String nickname;
private ServerModelManager model;
public ServerCommunicationThread(Socket connectionSocket,
ServerModelManager model) throws IOException {
this.connectionSocket = connectionSocket;
inFromClient = new ObjectInputStream(connectionSocket.getInputStream());
outToClient = new ObjectOutputStream(connectionSocket.getOutputStream());
this.model = model;
start();
}
public void run() {
try {
String nickname = (String) inFromClient.readObject();
if (model.exists(nickname)){
System.out.println(nickname + " already exists");
outToClient.writeObject(new MessageForClient("Please choose another nickname"));
}
else
{
System.out.println(nickname + " connected, adding to list");
model.addClient(nickname, connectionSocket,outToClient,inFromClient);
this.nickname=nickname;
}
while(true){
Object o= inFromClient.readObject();//StreamCorruptedexception
if(o instanceof RequestForGame)
{
RequestForGame r=(RequestForGame)o;
String userToPlayWith=r.getUserToPlayWith();
if(userToPlayWith.equals(nickname))
{
String message="Playing with yourself makes your palms hairy, choose another opponent";
outToClient.writeObject(message);
}
else
{
System.out.println("received request to play with "+userToPlayWith+". starting game");
ClientRepresentative client1=model.getClient(nickname);
ClientRepresentative client2=model.getClient(userToPlayWith);
ServerGameThread s=new ServerGameThread(client2,client1,client2.getInStream(),client1.getInStream(),client1.getOutStream(),client2.getOutStream());
}
}
else if(o instanceof String)
{
String s=(String) o;
if(s.equals("i want to quit"))
{
model.deleteClient(nickname);
inFromClient.close();
String q="quit";
outToClient.writeObject(q);
connectionSocket.close();
System.out.println(nickname+"has quit without exc");
}
}
}
} catch (EOFException e) {
System.out.println(nickname+" has quit");
}
catch (SocketException e)
{
System.out.println(nickname+" has quit");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public class ServerGameThread extends Thread {
private ClientRepresentative client1,client2;
private ObjectInputStream inFromClient1,inFromClient2;
private ObjectOutputStream outToClient1,outToClient2;
private Field gameField;
public ServerGameThread(ClientRepresentative client1, ClientRepresentative client2,ObjectInputStream inFromClient1,ObjectInputStream inFromClient2,ObjectOutputStream outToClient1,ObjectOutputStream outToClient2)
{
System.out.println("startin game thred");
this.client1=client1;//client 1 goes first
this.client2=client2;//client 2 started game
this.inFromClient1=inFromClient1;
this.inFromClient2=inFromClient2;
this.outToClient1=outToClient1;
this.outToClient2=outToClient2;
gameField=new Field();
System.out.println("check");
start();
}
public void run()
{
System.out.println("Starting game. players: "+client1.getNickname()+";"+client2.getNickname());
try {
outToClient1.writeObject(gameField);
outToClient2.writeObject(gameField);
while(true)
{
try {
System.out.println("listening to "+client1.getNickname());
Object o1=inFromClient1.readObject();//read move from client 1.**//StreamCorruptedexception**
while(!(o1 instanceof PlayerMove))
{
o1=inFromClient1.readObject();//read move from client 1.
}
PlayerMove move1=(PlayerMove)o1;
System.out.println("received move "+move1+" sending to "+client2.getNickname());
outToClient2.writeObject(move1);
System.out.println("listening to "+client2.getNickname());
Object o2=inFromClient2.readObject();//read move from client 1.
while(!(o2 instanceof PlayerMove))
{
o2=inFromClient2.readObject();//read move from client 1.
}
PlayerMove move2=(PlayerMove)o2;
System.out.println("received move "+move2+" sending to "+client1.getNickname());
outToClient1.writeObject(move2);
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
the model.addClient method though i don't think the problem is here
public void addClient(String nickname, Socket clientSocket,ObjectOutputStream stream,ObjectInputStream inStream)
{
clients.addClient(nickname, clientSocket,stream,inStream);//add to arraylist
//send client list to all clients
String[] users=this.getAvailableClients();
ObjectOutputStream[] streams=clients.getOutStreams();
for(int i=0;i<streams.length;i++)
{
try {
streams[i].writeObject(users);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The client side proxy that sends objects to server, the methods are triggered by user actions in GUI
public class Proxy {
final int PORT = 1337;
String host;
String nickname;
private Socket clientSocket;
private ObjectOutputStream outToServer;
private ObjectInputStream inFromServer;
private ClientModelManager manager;
public Proxy(String nickname,String host,ClientModelManager manager)
{
this.nickname=nickname;
this.host=host;
this.manager=manager;
this.connect(nickname);
}
public void connect(String nick)
{
Socket clientSocket;
try {
clientSocket = new Socket(host, PORT);
System.out.println("client socket created");
outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
inFromServer=new ObjectInputStream(clientSocket.getInputStream());
outToServer.flush();
outToServer.writeObject(nick);
ClientReceiverThread t=new ClientReceiverThread(inFromServer,manager);
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void makeRequest(String user)
{
try
{
outToServer.writeObject(new RequestForGame(user));
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void quit()
{
try {
outToServer.writeObject(new String("i want to quit"));
//clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMove(PlayerMove move)
{
try {
outToServer.writeObject(move);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This problem can happen if you
ObjectInputStream
or ObjectOutputStream
over the same socket instead of using the same ones for the life of the socket;This can also happen if the JVM reading the serialized object does not have the correct class/jar files for the object. This usually results in a ClassNotFoundException
, but if you have different jar/class versions and the serialVersionUID
was not changed between versions, a StreamCorruptedException
is produced. (This exception may also be possible if there is a class name conflict. e.g.: a jar containing a different class with the same full class name, though they probably also need the same serilVersionUID
).
Check that the client side has the correct versions of jars and class files.
There's another possibility that I ran across where if you implement a custom deserialization routine for a class by adding this method:
private void readObject( ObjectInputStream objectInputStream ) throws IOException
then objectInputStream.defaultReadObject() must be called and called before any further reads of the input stream to properly initialise the object.
I missed this and despite the object returning without an exception being thrown it was the next read of the object stream that confusingly raised the invalid type code exception.
This link provides further information on the process: http://osdir.com/ml/java.sun.jini/2003-10/msg00204.html.
I too had this exception. It occurred because I used two threads for Server class and Client class. I used one thread for object sending and receiving thing. Then it was ok. This is easy way to solve the problem if you are not familiar with synchronized
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With