DataInputStream, дающий java.io.EOFException

Я создал небольшое клиент-серверное приложение CLI. После загрузки сервера клиент может подключиться к нему и отправить команды на сервер.

Первая команда — получить список файлов, которыми загружен сервер.

Как только соединение сокета установлено. Я прошу пользователя ввести команду.

ClientApp.java

Socket client = new Socket(serverName, serverPort); 

Console c = System.console();
if (c == null) {
    System.err.println("No console!");
    System.exit(1);
}

String command = c.readLine("Enter a command: ");

OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(command);  

Затем сервер перехватывает команду пользователя и отправляет соответствующие ответы.

SeverApp.java —

Socket server = serverSocket.accept();
DataInputStream in = new DataInputStream(server.getInputStream());

switch (in.readUTF()){
    case "list":
        for (String fileName : files) {
            out.writeUTF(fileName);
        }
        out.flush();

}
server.close();

Затем клиент получает ответ сервера -

ClientApp.java

InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
String value;
while((value = in.readUTF()) != null) {
    System.out.println(value);
}

client.close();

files - это ArrayList, в котором я храню список файлов, загруженных на сервер. Когда клиент отправляет команду list на сервер, мне нужно отправить массив строк (список имен файлов) обратно. Точно так же приложение будет иметь больше команд.

Теперь, когда я делаю такой запрос, я получаю список файлов и строк java.io.EOFException из while((value = in.readUTF()) != null) {.

Как это исправить?


РЕДАКТИРОВАТЬ (РЕШЕНИЕ) ---

http://docs.oracle.com/javase/tutorial/essential/io/datastreams.html

Обратите внимание, что DataStreams обнаруживает состояние конца файла, перехватывая исключение EOFException вместо проверки недопустимого возвращаемого значения. Все реализации методов DataInput используют EOFException вместо возвращаемых значений.

try {
    while (true) {
        System.out.println(in.readUTF());
    }
    } catch (EOFException e) {
}

person ChamingaD    schedule 14.04.2014    source источник
comment
возможный дубликат Java FileInputStream ObjectInputStream достигает конца файла EOF   -  person donfuxx    schedule 14.04.2014


Ответы (3)


Метод readUTF никогда не вернет null. Вместо этого вы должны сделать:

while(in.available()>0) {
    String value = in.readUTF();

Глядя на javadocs, выбрасывается исключение EOFException, если этот входной поток достигает конца до чтения всех байтов.

person JamesB    schedule 14.04.2014

Используйте FilterInputStream.available()< /а>.

InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
String value;
while(in.available() > 0 && (value = in.readUTF()) != null) {
    System.out.println(value);
}

...
person Braj    schedule 14.04.2014
comment
Брай, у меня есть еще один вопрос. В моем коде я перебираю массив и отправляю данные клиенту один за другим. Можно ли отправить его один раз как string[] ? - person ChamingaD; 15.04.2014
comment
Извините, решение кажется неработающим. это дает java.net.SocketException: Software caused connection abort: socket write error от out.writeUTF(fileName); - person ChamingaD; 15.04.2014
comment
Это рабочий файл для меня. Пожалуйста, взгляните на мой обновленный пост. - person Braj; 15.04.2014
comment
Узнай разницу и скажи, что ты делал не так? - person Braj; 15.04.2014
comment
Проблема заключается в коде на стороне сервера, где вы закрыли сокет сервера serverSocket.close(); в цикле while и пытаетесь принять другой клиентский сокет на том же сокете сервера. Чтобы решить эту проблему, переместите serverSocket.close(); за пределы цикла while. - person Braj; 15.04.2014
comment
Я не использовал цикл while в своем коде на стороне сервера. сервер останавливается после передачи данных одному клиенту. но вы можете сделать это и для нескольких клиентов. - person Braj; 15.04.2014
comment
Если все еще есть какие-либо проблемы, попробуйте использовать BufferedReader вместо Scanner. Я обновил его в своем посте для кода на стороне клиента. - person Braj; 15.04.2014
comment
Если все еще не работает, удалите serverSocket.setSoTimeout(100000); из кода на стороне сервера. - person Braj; 16.04.2014
comment
Я думаю, что нашел решение. Спасибо за поддержку. Обновил мой вопрос. - person ChamingaD; 16.04.2014

http://docs.oracle.com/javase/tutorial/essential/io/datastreams.html

Обратите внимание, что DataStreams обнаруживает состояние конца файла, перехватывая исключение EOFException вместо проверки недопустимого возвращаемого значения. Все реализации методов DataInput используют EOFException вместо возвращаемых значений.

try {
    while (true) {
        System.out.println(in.readUTF());
    }
    } catch (EOFException e) {
}
person ChamingaD    schedule 16.04.2014