Закрывает ли BufferedReader / PrintWriter сокетное соединение? - PullRequest
16 голосов
/ 27 января 2009

У меня есть приложение, которое использует простые сокеты для передачи некоторых символов между двумя системами. У меня есть 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?

Ответы [ 4 ]

16 голосов
/ 27 января 2009

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

9 голосов
/ 27 января 2009

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

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

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

4 голосов
/ 28 января 2009

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

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

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

2 голосов
/ 27 января 2009

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

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