Поведение сокетов Java при закрытии потока вывода - PullRequest
20 голосов
/ 17 января 2012

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

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

  1. Открыть сокет, получить потоки ввода / вывода.
  2. Записьзапрос, закрытие потока
  3. чтение ответа, закрытие в потоке
  4. закрытие сокета.

Вот мой вопрос / проблема.

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

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

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

Ответы [ 2 ]

28 голосов
/ 17 января 2012

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

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 голосов
/ 17 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...