Закрывает ли BufferedReader/PrintWriter соединение сокета?

У меня есть приложение, которое использует простые сокеты для передачи некоторых символов между двумя системами. У меня есть приложение java, работающее как сервер. Я устанавливаю соединение нормально и даже передаю одно сообщение. Однако после отправки одного сообщения мое соединение закрывается.

Из того, что я могу сказать, кажется, что при закрытии printWriter и bufferedReader сам сокет закрывается?! Это плохо, поскольку у меня есть несколько сообщений для отправки по тому же соединению.

printWriter = new PrintWriter(theServer.getClientSocket().getOutputStream());
bufferedReader = new BufferedReader(new InputStreamReader(theServer.getClientSocket().getInputStream()));


printWriter.println("the line");

printWriter.close(); //Closing on these lines?
bufferedReader.close(); //Closing on these lines?

Неужели я его полна? Как я могу поддерживать это соединение в Java?

Ответ 1

Да, закрытие любого Writer/Reader закроет всех остальных писателей и читателей, которые они обернут. Не закрывайте его, пока не будете готовы закрыть основной сокет.

Ответ 2

Как @Eddie сказал (за несколько секунд до меня!:)), закрытие записи и/или читатель закроет основные потоки сокетов и сам сокет: Однако я считаю, что сам сокет не будет закрыт.

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

Вы не должны закрывать писателя и читателя. Просто промойте автора, чтобы убедиться, что ваши сообщения прибудут вовремя. Закрытие сокета позже приведет к закрытию соответствующих потоков, поэтому вам не нужно их закрывать самостоятельно. Просто оставьте объекты для чтения/записи в GC.

Ответ 3

Другой альтернативой является создание фильтров NoCloseInputStream и NoCloseOutputStream, которые просто ничего не делают при закрытии; затем используйте их для обертывания ваших потоков сокетов приложения (до того, как любое приложение будет обертовать как буфер).

Обратите внимание, что если вы должны это сделать, вам нужно будет сохранить ссылку на сокет (или обернутые потоки), чтобы вы могли закрыть сокет, когда вы на самом деле его сделали.

Чтобы ответить на комментарий, это "слишком продвинутая концепция для OP": проблема OP заключается в том, что при закрытии потока верхнего уровня он также закрывает базовый сокет, но это не хорошо, поскольку он хочет создать потоки верхнего уровня через сокет для отправки дополнительных сообщений. В зависимости от его архитектуры единственным способом добиться этого может быть обертка потоков в оболочках NoClose - например, он может передавать потоки в XML-сериализатор или десериализатор, который закрывает поток, когда он завершается, который закрывается вне его контроля.

Ответ 4

Вам нужно закрыть сокет после закрытия потоков.