StreamCorruptedException: invalid type code: AC

Hello!

I'm just writing a small application which is supposed to send serialized objects via network. The first object a client sends to the server is correctly answered by the server (sends an answer object). However, every further object the client sends causes a StreamCorruptionError on the server side. This problem occurs always when server and client are on localhost. If they are on two different machines it seems to work. Any ideas why is that?

I guess there is some conceptual mistake in my code. How to handle the ObjectOutputStreams and ObjectInputStreams correctly.

Here is the main client code:

publicclass Clientimplements Runnable, Base{

finalstaticint port = 1234;

String host="";

int timeOut = 0;

private Socket socket;

privateboolean close=false, connected;

protected Vector<Listener> listeners =new Vector<Listener>();

private Object NewObject =null;

public Client(String host){

this.host=host;

}

publicvoid run(){

close=false;

while(!close){

ObjectInputStream ois=null;

try{

if (socket==null || !socket.isConnected()){

socket =new Socket(host, port);

socket.setSoTimeout(timeOut);

connected=true;

}

ois =new ObjectInputStream(new BufferedInputStream( socket.getInputStream()));

}catch (Exception e){

e.printStackTrace();

close=true;

}

try{

NewObject = ois.readObject();

localSend(NewObject);

}catch (Exception e){

e.printStackTrace();

close=true;

}

}//while

//Connection closed -> clean up a little

try{

if (socket.isConnected())

socket.close();

socket=null;

}catch (IOException ioe){}

finally{

connected=false;

}

}

publicvoid closeConnection(){

close=true;

try{

if (socket!=null)

socket.close();

}catch (IOException ioe){}

}

publicvoid deleteListener(Listener listener){

if (listener!=null && this.listeners.contains(listener))

this.listeners.remove(listener);

}

publicvoid newListener(Listener listener){

if (listener!=null && !this.listeners.contains(listener))

this.listeners.add(listener);

}

publicsynchronizedvoid send(Object o){

ObjectOutputStream oos =null;

//debug

if (socket==null){

return;

}

try{

oos =new ObjectOutputStream(socket.getOutputStream());

}catch (Exception e){

}

try{

oos.writeObject(o);

oos.flush();

oos.reset();

}catch(Exception e){

}

}

/**

* Sends a received Object to the registered listeners

* listeners must implement the Listener interface

* @param o Object to send

*/

publicvoid localSend(Object o){

for (Iterator iter = listeners.iterator(); iter.hasNext();){

Listener element = (Listener) iter.next();

if (element!=null){

element.received(o);

}

}

}

publicvoid startConnection(){

try{

}catch (Exception e){e.printStackTrace();}

new Thread(this).start();

}

publicboolean isConnected(){

return connected;

}

}

This is the server:

publicclass Serverextends Clientimplements Runnable{

privatefinalstaticint maxClients=8;

private ServerSocket serverSocket=null;

private Vector<Socket> clientSockets =new Vector<Socket>();

private Vector<InetAddress> clientPorts =new Vector<InetAddress>();

private GameServer gs;

private ObjectInputStream ois;

privatestatic HashMap<Socket, ObjectOutputStream> ooss =new HashMap<Socket, ObjectOutputStream>();

public Server(){

gs=new GameServer(this);

this.newListener(gs);//to ensure the GameServer receives the objects sent by the clients

}

publicvoid run(){

try{

serverSocket =new ServerSocket(port);

Socket socket=null;

while (!close){

try{

socket = serverSocket.accept();

socket.setSoTimeout(timeOut);

if (!clientSockets.contains(socket) &&

!clientPorts.contains(socket.getInetAddress())){

clientSockets.add(socket);

clientPorts.add(socket.getInetAddress());

ooss.put(socket,new ObjectOutputStream(socket.getOutputStream())) ;

ServerThread st =new ServerThread(socket,new ObjectInputStream(new BufferedInputStream( socket.getInputStream())),this);

new Thread(st).start();

}

}catch (SocketTimeoutException se){

System.out.println(se.getMessage());

}catch (IOException ioe){

System.out.println(ioe.getMessage());

}

}

}catch (BindException be){//outer catch

System.out.println(be.getMessage());

}catch (Exception e){

if (e!=null){

System.out.println(e.getMessage());

}

}

}

/**

* Sends an object to the specified socket

* @param o the object to be sent

* @param socket of the client which is addressed

*/

publicsynchronizedvoid send(Object o,Socket socket){

ObjectOutputStream oos =null;

if (socket!=null && (socketinstanceof Socket) && socket.isConnected()){

try{

oos = ooss.get(socket);

}catch (Exception e){

}

try{

oos.writeObject(o);

oos.flush();

oos.reset();

}catch(Exception e){

}

}

}

publicvoid closeConnection(){

close=true;

try{

if (serverSocket!=null)

serverSocket.close();

}catch (IOException ioe){}

}

/**

* Sends a received Object to the registered listeners

* listeners must implement the Listener interface

* sends the receiving socket as well

* @param o Object to send

*/

publicvoid localSend(Object o, Socket socket){

if (o!=null && oinstanceof String){

Log.log((String) o);

return;

}

for (Iterator iter = listeners.iterator(); iter.hasNext();){

Listener element = (Listener) iter.next();

if (element!=null){

element.received(o, socket);

}

}

}

publicvoid removeClient(Socket socket){

if (socket!=null)

try{

ooss.remove(socket);

clientSockets.remove(socket);

clientPorts.remove(socket.getInetAddress());

GameServer.removePlayer(socket);

}catch (Exception e){

System.out.println(e.getMessage()+"\n");

}

}

}

This is the ServerThread (for listening):

publicclass ServerThreadextends Thread{

private Server server;

private Socket socket;

privateint numRetries=3;

private ObjectInputStream ois;

public ServerThread(Socket socket, ObjectInputStream ois, Server server){

this.socket=socket;

this.ois=ois;

this.server=server;

}

publicvoid run(){

boolean close=false;

int tries=0;

Object NewObject;

while(!close){

//read object from inputstream

try{

NewObject = ois.readObject();

server.localSend(NewObject, socket);

}catch (StreamCorruptedException sce){

System.out.println("StreamCorruptedException :-(.\n");

System.out.println(sce.getMessage()+"\n"+sce.getStackTrace()+"\n");

sce.printStackTrace();

close=true;

}catch (ClassNotFoundException ce){

System.out.println(ce.getMessage()+"\n");

close=true;

}catch (IOException ioe){

System.out.println(ioe.getMessage()+"\n");

ioe.printStackTrace();

close=true;

}catch (Exception e){

System.out.println(e.getMessage()+"\n"+e.toString()+"\n");

System.out.println("Socket: "+socket.toString()+"\n");

if (tries<=numRetries){

tries++;

continue;

}

close=true;

}

}// while

//remove socket from list of clients

server.removeClient(socket);

}

}

Thanks for your help in advance.

Yours,

Peter

[18333 byte] By [peter_gera] at [2007-11-27 5:38:04]
# 1

You must create the ObjectInputStream and the ObjectOutputStream for the life of the socket at both ends, or anew for each ob ject at both ends. Not a mixture of the two.

Also you should always close the output stream of a socket before closing its input stream or the socket itself, which in fact are redundant once you've closed the output stream.

ejpa at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 2
Thanks a lot!You've been perfectly right.
peter_gera at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 3
Hi, could you write, what you changed in code, that now is right? I have more or less similar problem and don't know how to solve it. Thanks for helpMike
Lazika at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 4
See reply #1.
ejpa at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 5

Ok, I have a little bit difrent problem, but maybe you can help me.

I have two sides, which want to comunicate each other. Both of them ae listening for connection from the other one, and one connection arrived, the connection is establish. The problem is, when I would like to disconnect (for example by Disconet button on on of the sides).

Both sides implementes class comunicator, which handles serverThread (for listening for arriving connection) and clientThread (to create when connecting, or when connection arvied). Clases for communicator, ServerThread, and Client thread looks like this:

public class Communicator {

private Socket socket;

private ServerSocket serverSocket;

private UserInputDataThread thread;

private UserServerThread serverthread;

private int port;

public Communicator(int port) {

try{

serverSocket = new ServerSocket(port);

}

catch(Exception e) {

System.out.println("Tworzymy comunicator:"+e);

}

this.port=port;

serverthread=new UserServerThread(serverSocket);

serverthread.start();

}

//for connecting with other side

public Socket connect(String host, int port) {

try{

socket = new Socket(host,port);

thread = new UserInputDataThread(socket, user ,userWindow);

thread.start();

System.out.println("Watek startuje. ");

}

catch(Exception e) {

System.out.println("W metodzie Connect: "+e);

}

return socket;

}

//for disconnecting with other side

public void disconnect() {

System.out.println("Disconnect");

thread.sendMessage(new Disconnect());

thread.Stop();

userWindow.getConnectionWindow().DisplayMessage("Connection closed.\n");

userWindow.DisplayBottomMassage("Disconnected");

System.out.println("Rozlaczenie");

}

public void setThread( UserInputDataThread thread) {

this.thread = thread;

}

}

//Server Thread for listining for conections

public class UserServerThread extends Thread{

ServerSocket serverSocket;

UserInputDataThread thread;

Socket socket;

public UserServerThread(ServerSocket serverSocket) {

this.serverSocket=serverSocket;

}

public void run() {

while(true) {

try{

socket = serverSocket.accept();

thread= new UserInputDataThread(socket);

thread.start();

user.getCommunicator().setThread(thread);

}

catch(IOException e) {

//System.out.println("W watku servera: "+e);

}

}

}

public class UserInputDataThread extends Thread{

protected Socket socket;

protected boolean state=true;

ObjectInputStream Objectin;

ObjectOutputStream Objectout;

//Client thread

public UserInputDataThread(Socket socket, {

this.socket = socket;

state=true;

}

public void run() {

Message message;

try{

Objectout = new ObjectOutputStream(socket.getOutputStream());

Objectin = new ObjectInputStream(socket.getInputStream());

while(state) {

try{

message = (Message)Objectin.readObject();

user.receivedMessage(message, new CommunicatorAddress(socket));

if(message.getClass().getName()=="Disconnect") {

System.out.println("Dostalismy wiadomosc Disconnect");

userWindow.getConnectionWindow().setConnectButtons();

userWindow.DisplayBottomMassage("Disconnected");

Stop();

return;

}

//user.receivedMessage(message, new CommunicatorAddress(socket));

}

catch (Exception ex) {

System.out.println("1. W watku: "+ex);

Stop();

return;

}

}

}

catch(Exception e) {

System.out.println("Przy tworzeniu strumieni"+e);

}

}

public void sendMessage(Message message) {

try{

Objectout.writeObject(message);

Objectout.flush();

}

catch(Exception e)

{

System.out.println("Przy wysylaniu: "+e);

}

}

public void Stop() {

state=false;

try {

Objectout.close();

Objectout=null;

}

catch(Exception e)

{

System.out.println("Przy stop: "+e);

}

}

}

Everything works fine untill I do disconnect(). I send to the other side Message ("Disconnect) (class message is Serializable) and the other side close the output stream and socket.

But the side, which run disconected() in the thread UserInputThread give me exception java socket closed.

I thought, maybe because later I'm closing outputstream, so i commented this,and later i got the exception EOF Exception.

Could you tell me what I'm doing wrong, or how should look disconnecting with 2 sides?

Thanks for help

Lazik

Lazika at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 6
'Socket closed' means that you closed it yourself. Closing either the input stream or the output stream does that.You don't really need the 'disconnect' message. Just close the socket. The reading end will get an EOFException, on which it should close its end. Finito.
ejpa at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 7

Thanks a lot, I modify my code but I still have one problem.

The side, which is runing disconnect() should run thread.stop() and the output stream should be close. And is closing, but before it, I get 2 exception.

1. In runing thread: socket closed

2. In thread.stop() java.langNullPointerException.

Why I am getting these exception, when calling thread.stop?

Thanks for answer.

Lazik

Lazika at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...
# 8
Thread.stop() is deprecated and seriously dangerous. Don't call it. Read the Javadoc and see why.If you close a socket while another thread is reading it, of course it will get a 'socket closed' exception. What did you expect?
ejpa at 2007-7-12 15:11:05 > top of Java-index,Core,Core APIs...