Подтвердить что ты не робот

Поведение Java-сокетов при закрытии выходного потока

Может кто-нибудь объяснить следующее поведение в Java-сокетах:

Общая идея такова:

  • Открыть сокет, получить потоки ввода-вывода.
  • Запрос на запись, Закрыть поток
  • Читать отзыв, Закрыть в потоке
  • Закрыть сокет.

Здесь мой вопрос/вопрос.

Если я использую PrintWriter для вывода, а затем закрою его, он закрывает весь сокет, а последующая операция чтения терпит неудачу.

Вместо этого, если я напрямую использую метод socket shutdownOutput(), он правильно закрывает канал выходного потока, сохраняя его в живом виде.

Зачем закрывать объект PrintWriter, чтобы весь сокет был с ним связан?

4b9b3361

Ответ 1

Это может выглядеть так:

Socket socket;
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.close();

Теперь давайте посмотрим на описание метода getOutputStream() для Socket.

getOutputStream

public OutputStream getOutputStream() throws IOException

Возвращает выходной поток для этого сокета. Если этот сокет имеет связанный канал, то результирующий выходной поток делегирует все свои операции каналу. Если канал находится в неблокирующем режиме, то операции записи выходного потока будут вызывать IllegalBlockingModeException.

Закрытие возвращенного OutputStream закроет связанный сокет.

Возврат:

выходной поток для записи байтов в этот сокет.

Броски:

IOException - если возникает ошибка ввода-вывода при создании выходного потока или если сокет не подключен.

из приведенного выше описания, мы знаем, что закрытие возвращаемого OutputStream закрывает связанный сокет.

Теперь, когда вы закроете PrintWriter, он закроет связанный OutputStream, который закроет связанный сокет.

Ответ 2

Вероятно, потому, что вызов метода close() PrintWriter отслеживается через иерархию и вызывает метод close() для SocketOutputStream. В качестве части метода close() для SocketOutputStream он также вызывает метод close() для Socket, который в тоже время закроет SocketInputStream. Вызов функции shutdownOutput() вместо этого отправляет все ранее записанные данные, за которыми следует обычная последовательность завершения TCP-соединения. Затем он отключает выходной поток.