EOFException DataInputStream с использованием readUTF

Я закодировал простой сервер, который прослушивает клиента, и когда клиент подключен, он открывает поток ввода данных, который считывает все данные, отправленные от клиента (мой клиент пишет данные UTF).

Это код сервера:

    @Override
public void run() {
    // TODO Auto-generated method stub  
    try {           
        ServerSocket ss = new ServerSocket(7000);
        while(true){
        System.out.println("Il Server sta cercando Connessioni");
        Socket s = ss.accept();
        System.out.println("Il Server ha accettato un Client");

        Thread t2 = new Thread(new Runnable(){
            public void run(){             
                   try {
                    while(true){
                    DataInputStream dis = new DataInputStream(s.getInputStream());
                    isAlreadyOpened = true;                     
                    System.out.println(dis.readUTF());
                    }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    isAlreadyOpened = false;
                }  
            }           
        });
        if(!isAlreadyOpened){
        t2.start();
        }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Это очень просто, и мой клиент - это приложение Andorid, которое отправляет данные при нажатии кнопки:

 @Override
public void onClick(View v) {
    try {
        DataOutputStream out = new DataOutputStream(s.getOutputStream());
        out.writeUTF("Testiamo sto socket");
        out.flush();
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

Все идеально, когда клиент подключен к серверу. Но когда я нажимаю кнопку «Клиент» только один раз, отправленные данные отображаются в журналах моего сервера, но сразу после создания исключения.

Il Server sta cercando Connessioni
Il Server ha accettato un Client
Il Server sta cercando Connessioni
Testiamo sto socket
java.io.EOFException
   at java.io.DataInputStream.readUnsignedShort(Unknown Source)
   at java.io.DataInputStream.readUTF(Unknown Source)
   at java.io.DataInputStream.readUTF(Unknown Source)

читая из документации Oracle, это исключение выдается ‹>. Но как мне этого избежать?


person Alessio Trecani    schedule 07.02.2016    source источник
comment
Вы пытались поставить оператор if перед readuTF, например if(dis.readUTF() != null){do the stuff}   -  person Briesanji    schedule 07.02.2016
comment
Да, я пробовал. Но это не работает. Выдает исключение. Но данные ни разу не печатаются. Так что я думаю, что это хуже, чем раньше..   -  person Alessio Trecani    schedule 07.02.2016
comment
Операторы while(true)... неэффективны, и их следует избегать. EOFException — это исключение конца файла. Так что это означает, что вы делаете что-то не так (возможно, читаете несуществующие вещи).   -  person xdevs23    schedule 07.02.2016
comment
В то время как (true) установлено, чтобы позволить серверу прослушивать данные вечно. Я не думаю, что есть альтернативный способ сделать это. Проблема в том, что когда клиент отправляет данные, сервер может их прочитать. Но поскольку он находится внутри цикла while.. во второй раз нет данных для читать, поэтому он выдает исключение. И это то, чего я хотел бы избежать, даже если мне нужен сервер, который каждый раз прослушивает данные.   -  person Alessio Trecani    schedule 07.02.2016
comment
@ xdevs23 Ваше заявление о неэффективности while (true) утверждений - 100% ерунда. Ничто не может быть более эффективным.   -  person user207421    schedule 07.02.2016
comment
@Briesanji Этот метод не возвращает null. См. Javadoc.   -  person user207421    schedule 07.02.2016


Ответы (2)


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

Здесь нет проблемы, которую нужно решить. Если вам нужно отправить больше строк по тому же соединению, не закрывайте его после отправки.

person user207421    schedule 07.02.2016
comment
О, спасибо за ответ.. я не понял. Я думал, что соединение не было закрыто, потому что на стороне сервера все хорошо. Проблема заключалась в том, что клиент после сброса выходного потока закрыл сокет. Я просто удалил dos.close() и все заработало. Большое спасибо - person Alessio Trecani; 07.02.2016

Хотя это не было проблемой Алессо, вот еще один способ возникновения исключения EOFException:

Вы открываете поток вывода в файл, а затем открываете поток ввода в тот же файл, не закрывая сначала поток вывода.

person Tom Rutchik    schedule 07.12.2020