Клиентские сокеты по протоколу TCP/IP в Java

Клиентские сокеты по протоколу TCP/IP в JavaСокеты по протоколу ТСР/IP служат для реализации надежных двунаправленных, постоянных, двухточечных, потоковых соединений между хостами в Интернете.

Сокет может служить для подключения системы ввода-вывода в Java к другим программам, которые могут находиться как на локальной машине, таки на любой другой машине в Интернете.

В Java поддерживаются две разновидности сокетов по протоколу ТСР /IP: один — для серверов, другой — для клиентов.

Класс ServerSocket служит «приемником», ожидая подключения клиентов прежде, чем предпринять какие-нибудь действия. Иными словами, класс ServerSocket предназначен для серверов, тогда как класс Socket — для клиентов.

Он служит для подключения к серверным сокетам и инициирования обмена данными по сетевому протоколу. Клиентские сокеты чаще всего применяются в прикладных программах на Java.

При создании объекта типа Socket неявно устанавливается соединение клиента с сервером.

Выявить это соединение нельзя никакими методами или конструкторами. Ниже перечислены два конструктора класса Socket, предназначенные для создания клиентских сокетов.

В классе Socket определяется ряд методов экземпляра. Например, объект типа Socket может быть просмотрен в любой момент для извлечения сведений о связанных с ним адресе и порте. Для этого применяются методы, перечисленные ниже.

  • InetAddress getInetAddress() — возвращает объект типа InetAddress, связанный с объектом типа Socket. Если же сокет не подключен, возвращается значение null
  • int getPort() — возвращает удаленный порт, к которому привязан вызывающий объект типа Socket. Если же сокет не привязан, возвращается нулевое значение
  • int getLocalPort() — возвращает локальный порт, к которому привязан вызывающий объект типа Socket. Если же сокет не привязан, возвращается значение -1

Для доступа к потокам ввода-вывода, связанным с классом Socket, можно вос­пользоваться методами getInputStream() и getOuptutStream(), перечислен­ными ниже.

Каждый из этих методов может сгенерировать исключение типа IOException, если сокет оказался недействительным из-за потери соединения.

Эти потоки ввода-вывода используются для передачи и приема данных таким же образом, как и потоки ввода-вывода.

  • InputStream getInputStream() throws IOException — возвращает объект типа InetAddress, связанный с вызывающим сокетом
  • OutputStream getOutputStream() throws IOException — возвращает объект типа OutputStream, связанный с вызывающим сокетом

Имеется и ряд других методов, в том числе метод connect(), позволяющий указать новое соединение; метод isConnected(), возвращающий логическое зна­чение true, если сокет подключен к серверу; метод isBound(), возвращающий ло­гическое значение true, если сокет привязан к адресу; а также метод isClosed(), возвращающий логическое значение true, если сокет закрыт.

Чтобы закрыть со­кет, достаточно вызвать метод close(). Закрытие сокета приводит также к закры­тию связанных с ним потоков ввода-вывода.

Начиная с версии JDК 7 класс Socket реализует также интерфейс AutoCloseabe. Это означает, что управление соке­ том можно организовать в блоке оператора try с ресурсами.

Приведенная ниже программа служит простым примером применения класса Socket. В этой программе устанавливается соединение с портом «whois» (номер 43) на Tcinet-cepвepe, посылается аргумент командной строки через сокет, а затем вы­водятся возвращаемые данные.

Tcinet-cepвep пытается интерпретировать аргу­мент как зарегистрированное доменное имя Интернета, а затем возвращает IР-адрес и контактную информацию из веб-сайта, найденного по этому доменному имени.

Если запросить, например, сведения об адресе pro-java.ru, то будет получен результат, аналогичный следующему:

Эта программа на Java действует следующим образом. Сначала в ней создается объект типа Socket, обозначающий сокет и задающий имя хоста «whois.tcinet.ru» и номер порта 43.

Затем в сокете открываются потоки ввода-вывода. Далее формируется символьная строка, содержащая имя веб-сайта, сведения о котором требуется получить.

Если веб-сайт не указан в командной строке, то выбирается имя хоста «pro-java.ru». Эта символьная строка преобразуется в массив байтов и направляется в сеть через сокет.

После этого ответ читается из сокета, а резуль­тат выводится на экран. И наконец, сокет закрывается, а вместе с ним и потоки ввода-вывода. В данном примере сокет закрывается вручную в результате вызова метода close().

Если же используется комплект версии JDК 7, то для автомати­ческого закрытия сокета можно организовать блок оператора try с ресурсами. В качестве примера ниже приведен другой способ написать метод main() из рас­сматриваемой здесь программы, чтобы закрывать сокет автоматически.

В своем прикладном коде следует уделить внимание автоматическому управлению сетевыми ресурсами, по­скольку это более рациональный и гибкий подход.

Следует также иметь в виду,что в данной версии программы исключения все еще генерируются в теле метода main(), но их можно было бы перехватывать и обрабатывать, добавив операторы catch в конце блока оператора try с ресурсами.

Интересное видео на сегодня: