user4359659
user4359659

Reputation: 159

EOFException in a Java client-server app

I'm developing a simple client-server clock, which transmits the current time to all clients, hosted by the clock server application. There is a timed event (TimerTask) that sends the data periodically to all clients. And at the Server part it works fine, but when the client runs, it reads the time only once, even though it's in a while loop - it jumps to the catch block and raises EOFException. It's throwny most likely by readUTF() method in the while loop. How can I counteract it?

public class Client {

public static void main(String[] arg) {


    Socket socketConnection = null;
    ObjectOutputStream clientOutputStream = null;
    ObjectInputStream clientInputStream = null;

    try {

        socketConnection = new Socket("127.0.0.1", 11111);

        clientOutputStream = new ObjectOutputStream(
                socketConnection.getOutputStream());
        clientInputStream = new ObjectInputStream(
                socketConnection.getInputStream());     

        while(true){
            String date = clientInputStream.readUTF();
            clientOutputStream.flush();
            System.out.println(date);

        }

    } catch (Exception e) {
        System.out.println("The following exception has occured and was caught:");
        System.out.println(e);
    }

    finally{
        try {
            clientOutputStream.close();
            clientInputStream.close();              
            socketConnection.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}

I could, for example, put the entire try/catch/finally block in a while loop, and then it works fine. But this way my client disconnects and reconnects to the server every single second, which is unacceptable. Any ideas?

EDIT - stacktrace:

java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at task2.Client.main(Client.java:28)

EDIT - server code:

public class Server {

 public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;

        boolean listeningSocket = true;
        try {
            serverSocket = new ServerSocket(11111);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 11111");
        }


        while(listeningSocket){
            System.out.println("Waiting for a client to connect...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected!");
            ConnectThread ct = new ConnectThread(clientSocket);
            ct.start();
        }
        System.out.println("closed");
        serverSocket.close();       
    }

}

Server keeps listening for incoming clients, and every time it accepts a connection, it starts conversation on a separate thread, defined by the following class:

public class ConnectThread extends Thread{

private Socket socket = null;
public ConnectThread(Socket socket) {
    super("ConnectThread");
    this.socket = socket;
}

@Override
public void run(){
    ObjectOutputStream serverOutputStream = null;
    ObjectInputStream serverInputStream = null;
    try {           
        serverOutputStream = new ObjectOutputStream(socket.getOutputStream());          
        serverInputStream = new ObjectInputStream(socket.getInputStream());

        ClockTask ctask = new ClockTask();
        Timer timer = new Timer();
        timer.schedule(ctask, 0, 1000);

        Thread.sleep(1000);
        serverOutputStream.writeUTF(ctask.date);
        serverOutputStream.flush();


    } catch (IOException | InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally{
        try {
            serverOutputStream.close();
            serverInputStream.close();              
            socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }       
}
}

which schedules periodic date update:

public class ClockTask extends TimerTask {

public Calendar c;
public String date;

@Override
public void run() {
    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");       
    this.c = Calendar.getInstance();
    this.date = dateFormat.format(c.getTime());
}

}

Upvotes: 0

Views: 1868

Answers (2)

laune
laune

Reputation: 31300

You need a loop in the run of ConnectThread - as it is, it stops and the stream is closed.

Edit the Code:

ClockTask ctask = new ClockTask();
Timer timer = new Timer();
timer.schedule(ctask, 0, 1000);
while( true ){
    Thread.sleep(1000);
    serverOutputStream.writeUTF(ctask.date);
       serverOutputStream.flush();
}

Upvotes: 2

jtahlborn
jtahlborn

Reputation: 53694

Your server writes the date once to the stream and then closes. hence, the client gets and EOFException after the first read.

Upvotes: 2

Related Questions