java.io.EOFException (having problems with closing streams)

3.1k Views Asked by At

Got a simple client/server app only with login/logout implemented. When i press connect it runs perfect, but the problem comes after when trying to disconnect (getting EOFException on client side). Im almost sure its due to a poor close of the stream. Any hints?

java.io.EOFException
    at java.io.DataInputStream.readByte(DataInputStream.java:98)
    at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:506)
    at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:778)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
    at com.mtm.ClientConnection.disconnect(ClientConnection.java:54)**

Client class:

public class ClientConnection implements Admin{

    public ObjectInputStream in;
    public static ObjectOutputStream out;
    public Socket socket;

    public void connect(){

        String host = IP;
        int port = PORTO;

        try {       
            socket = new Socket (host,port);
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());           

            MSG_Login login = new MSG_Login();         
            login.setID(DeviceId.getId().toString());
            send(login);   

            Object c1 = in.readObject();
            if(c1 instanceof MSG_Login){
                Thread thread = new ClientThread(this);
                thread.start();
            }

        }
        catch (UnknownHostException e) {        e.printStackTrace(); }
        catch (SocketException e) {             e.printStackTrace(); }
        catch (IOException e) {                 e.printStackTrace(); }
        catch (ClassNotFoundException e) {      e.printStackTrace(); }
    }

    public void disconnect(){
        try {
            MSG_Logout logout = new MSG_Logout();
            logout.setID(DeviceId.getId().toString());
            send(logout);

            Object c1 = in.readObject();
            if(c1 instanceof MSG_Logout){
                in.close();
                out.close();
                socket.close();
            }
        } 
        catch (IOException e) {  e.printStackTrace(); }
        catch (ClassNotFoundException e) {      e.printStackTrace(); }
    }

    public static void send(Object obj) {
        try {
            out.writeObject(obj);
            out.flush();
            out.reset();
        }
        catch (IOException e) { e.printStackTrace(); }
    }
}

Server (thread) class:

public class Servidor_Thread extends Thread{

    public Socket canal;
    Servidor serv;
    ObjectOutputStream oos=null;
    ObjectInputStream ois=null;
    private boolean logOff;

    public Servidor_Thread(Servidor serv) {
        this.serv = serv;
        canal = serv.socket;
        logOff = false;
    }

     public void run(){
            try {
                ois=new ObjectInputStream(canal.getInputStream());
                oos=new ObjectOutputStream(canal.getOutputStream());
                while(logOff==false){
                    Object obj=ois.readObject();/** Objecto recebido - Reconstrução **/
                    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    Date date = new Date();
                    if(obj instanceof MSG_Login){
                        serv.id_database.add(((MSG_Login) obj).getID());
                        serv.getLog().appendConsole("["+dateFormat.format(date)+"]..........User "+((MSG_Login) obj).getID()+" connected.");
                        enviar(obj);
                    }
                    if(obj instanceof MSG_Logout){
                        serv.id_database.remove(((MSG_Logout) obj).getID());
                        serv.getLog().appendConsole("["+dateFormat.format(date)+"]..........User "+((MSG_Logout) obj).getID()+" disconnected.");
                        enviar(obj);
                        stopThread();
                    }
                } 
            }
            catch (IOException e) {                  stopThread();      }
            catch (ClassNotFoundException e) {       e.printStackTrace();   } 
     }

     public void stopThread(){
        logOff = true;
        try {
            ois.close();
            oos.close();
            canal.close();
        } catch (IOException e) {   e.printStackTrace();    }
     }

     public void enviar(Object obj) {
        try {
            oos.writeObject(obj);
            oos.flush();
            oos.reset();
        } 
        catch (IOException e) { e.printStackTrace(); }
     }
}
1

There are 1 best solutions below

0
On

There is no problem here to answer. The readObject() method throws EOFException at end of stream. This is its normal behaviour. You have to catch it, close the stream you are reading, and exit the reading loop.