EOFException в клиент-серверном приложении Java

Я разрабатываю простые часы клиент-сервер, которые передают текущее время всем клиентам, размещенным приложением сервера часов. Существует синхронизированное событие (TimerTask), которое периодически отправляет данные всем клиентам. И на серверной части все работает нормально, но когда клиент запускается, он считывает время только один раз, даже несмотря на то, что находится в цикле while - он переходит к блоку catch и вызывает EOFException. Скорее всего, это вызвано методом readUTF() в цикле while. Как я могу противодействовать этому?

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();
        }
    }


}

Я мог бы, например, поместить весь блок try/catch/finally в цикл while, и тогда он работал бы нормально. Но таким образом мой клиент отключается и снова подключается к серверу каждую секунду, что неприемлемо. Любые идеи?

РЕДАКТИРОВАТЬ - трассировка стека:

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)

РЕДАКТИРОВАТЬ - код сервера:

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();       
    }

}

Сервер продолжает прослушивать входящих клиентов, и каждый раз, когда он принимает соединение, он начинает диалог в отдельном потоке, определяемом следующим классом:

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();
        }
    }       
}
}

который планирует периодическое обновление даты:

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());
}

}

person user4359659    schedule 03.01.2015    source источник
comment
Где трассировка стека? Это ваше соединение внезапно обрывается?   -  person SMA    schedule 03.01.2015
comment
И нет, сервер по-прежнему сохраняет стабильность, просто программа-клиент вылетает.   -  person user4359659    schedule 03.01.2015
comment
Возможно сервер закрывает поток/сокет, а клиент видит EOF. Взглянуть на код сервера?   -  person laune    schedule 03.01.2015
comment
Чтобы повысить шансы на получение ответов и их качество, предоставьте полный, но краткий код, необходимый для воспроизведения вашей проблемы. В настоящее время нет кода для сервера, поэтому мы можем только догадываться, что может пойти не так, и почему readUTF не может прочитать свои данные.   -  person Pshemo    schedule 03.01.2015
comment
Нет необходимости в clientOutputStream.flush(); или использовать этот поток вообще (если это не просто заполнитель для запланированного добавления)   -  person laune    schedule 03.01.2015
comment
Да, это просто заполнитель. И удаление не помогает. Добавил весь мой код, см. правки.   -  person user4359659    schedule 03.01.2015


Ответы (2)


Нужен цикл в запуске ConnectThread — как есть, он останавливается и поток закрывается.

Отредактируйте код:

ClockTask ctask = new ClockTask();
Timer timer = new Timer();
timer.schedule(ctask, 0, 1000);
while( true ){
    Thread.sleep(1000);
    serverOutputStream.writeUTF(ctask.date);
       serverOutputStream.flush();
}
person laune    schedule 03.01.2015
comment
Я даже думаю, что ClockTask может быть вне цикла — достаточно один раз запланировать событие, и оно все равно повторяется. - person user4359659; 03.01.2015

Ваш сервер один раз записывает дату в поток, а затем закрывается. следовательно, клиент получает исключение EOFException после первого чтения.

person jtahlborn    schedule 03.01.2015