ГЛАВА fjjjjt Сеть Как известно читателям, Java — практически синоним программирования для Интернета. Тому есть множество причини не последняя из них — способность создавать безопасный, межплатформенный и переносимый код. Однако одна из наиболее важных причин того, что Java является великолепным языком сетевого программирования, кроется в классах, определенных в пакете j a v a . n e t . Они обеспечивают легкие в использовании средства, с помощью которых программисты всех уровней квалификации могут обращаться к сетевым ресурсам. Эта глава посвящена пакету j a v a . n e t . Важно подчеркнуть, что сети — очень обширная и сложная тема. В настоящей книге невозможно полностью охватить все средства, содержащиеся в пакете j a v a . n e t . Поэтому в данной главе сосредоточим внимание лишь на некоторых основополагающих классах и интерфейсах. Основы работы с сетью Прежде чем начать, полезно будет получить представление о ключевых концепциях и терминах, связанных с сетями. В основе сетевой поддержки Java лежит концепция сокета (socket); сокет идентифицирует конечную точку сети. Парадигма сокета появилась в версии 4.2 BSD Berkley UNIX в самом начале х гг. По этой причине также используется термин сокет Беркли Сокеты — основа современных сетей, поскольку сокет позволяет отдельному компьютеру обслуживать одновременно как множество разных клиентов, таки множество различных типов информации. Это достигается за счет использования порта (port) — нумерованного со кета на определенной машине. Говорят, что серверный процесс слушает порт до тех пор, пока клиент не соединится с ним. Сервер в состоянии принять множество клиентов, подключенных к одному и тому же номеру порта, хотя каждый сеанс является уникальным. Чтобы обработать множество клиентских соединений, серверный процесс должен быть многопоточным либо обладать какими-то другими средствами обработки одновременного ввода-вывода. Сокетные коммуникации происходят по определенному протоколу. Протокол Интернета (Internet Protocol — IP) — это низкоуровневый маршрутизирующий протокол, который разбивает данные на небольшие пакеты и посылает их через сеть по определенному адресу, что не гарантирует доставки всех этих пакетов поэтому адресу. Протокол управления передачей (Transmission Control Protocol — TCP) является протоколом более высокого уровня, обеспечивающим надежную сборку этих пакетов, сортировку и повторную передачу, необходимую для надежной доставки данных. Еще один протокол — протокол пользовательских дейтаграмм (User Datagram Protocol — UDP), стоящий непосредственно за протоколом TCP, — может быть использован непосредственно для поддержки быстрой, не требующей постоянного соединения и ненадежной транспортировки пакетов 6 7 Часть II. Библиотека Как только соединение установлено, применяется высокоуровневый протокол, зависящий от используемого порта. Протокол T C P /IP резервирует первые 1024 порта для специфических протоколов. Многие из них покажутся вам знакомыми, если вы хоть какое-то время потратили на путешествия по просторам Интернета. Порт номер 21 предназначен для протокола FTP, для Telnet, для электронной почты, 43 — для whois, 80 — для протокола HTTP, 119 — для netnews; список можно продолжать. Каждый протокол определяет, как клиент должен взаимодействовать с портом. Например, HTTP — это протокол, используемый серверами и веб-браузерами для передачи гипертекста и графических изображений. Это довольно простой протокол для базового постраничного просмотра информации, предоставляемой веб серверами. Посмотрим, как он работает. Когда клиент запрашивает файл с сервера HTTP, это действие известно как попадание (hit) и заключается в простой отправке имени файла в определенном формате на предопределенный порт с последующим чтением содержимого этого файла. Сервер также сообщает код состояния, чтобы известить клиента о том, был ли запрос обработан и по какой причине. Ключевым компонентом Интернета является адрес Каждый компьютер в Интернете обладает собственным адресом. Адрес Интернета представляет собой число, уникально идентифицирующее каждый компьютер в Интернете. Изначально все адреса Интернета состояли из битовых значений, организованных в четыре битовых значения. Адрес такого типа определен IPv4 (Протокол Интернета версии 4). Однако в последнее время на сцену выступает новая схема адресации, называемая IPv6, которая предназначена для того, чтобы поддержать гораздо большее адресное пространство, чем IPv4. К счастью, имея дело cjava, вам обычно не придется беспокоиться о том, используется адрес IPv4 или IPv6, поскольку Java позаботится обо всех деталях. Точно также как адрес описывает сетевую иерархию, имя адреса Интернета, называемое доменным именем, представляет местонахождение машины в пространстве имен. Например, адрес www. H e r b S c h i l d t . com относится к верховному домену сот зарезервированному для коммерческих сайтов США, имеет имя H e r b S c h i l d t по названию компании, a www идентифицирует сервер, обрабатывающий веб-запросы. Доменное имя Интернета сопоставляется с адресом при помощи службы доменных имен (Domain Name Service — DNS). Это позволяет пользователям работать с доменными именами, в то время как Интернет оперирует 1Р-адресами. Сетевые классы и интерфейсы Язык Java поддерживает протокол T C P /IP как за счет расширения уже имеющихся интерфейсов потокового ввода-вывода, представленных в главе 19, таки за счет добавления средств, необходимых для построения объектов ввода-вывода в сети. Java поддерживает семейства протоколов как TCP, таки. Протокол TCP применяется для надежного потокового ввода-вывода посети. Протокол UDP поддерживает более простую, а потому быструю модель передачи дейтаграмм от точки к точке. Классы, содержащиеся в пакете j a v a . n e t , перечислены ниже Глава 21. Сеть 6 7 9CookieManagerMulticastSocketS tandardSocketOption Добавлено в JDK 7) DatagramPacketNetPermissionURIDatagramSocketNetworklnterfaceURLDatagramSocketImplPasswordAuthenticationU RLClassLoaderHttpCookieProxyURLConnect Интерфейсы пакета j ava. net перечислены далее Добавлено в JDK 7) URLStreamHandlerFactory CookieStore SocketImplFactory DatagramSocketImplFactory SocketOption Добавлено в JDK В следующем разделе рассмотрим основные сетевые классы и продемонстрируем несколько примеров их применения. Как только поймете устройство сетевых классов, сможете строить собственные на их основе. Класс Рассматриваемый класс используется для инкапсуляции как числового IP- адреса, таки его доменного имени. Вы взаимодействуете с классом, используя имя IP-хоста, что намного удобнее и понятнее, чем адрес. Класс InetAddress скрывает внутри себя число. Он может работать как с адресами IPv4, таки с IPv6. Методы-фабрики Класс InetAddress не имеет видимых конструкторов. Чтобы создать объект класса InetAddress, следует использовать один из доступных методов-фабрик. Методы-фабрики (factory m ethod) — это просто соглашение, в соответствии с которым статические методы класса возвращают экземпляр этого класса. Это используется вместо перегрузки конструктора с различными списками параметров, когда наличие уникальных имен методов делает результат более ясным. Ниже приведено три часто используемых метода-фабрики класса InetAddress. static InetAddress getLocalHost( ) throws UnknownHostException static InetAddress getByName(String имяХоста) throws UnknownHostException static InetAddress[ ] getAllByName(String имяХоста) throws Метод getLocalHost () возвращает объект класса InetAddress, представляющий локальный хост, метод getByName ( ) — объект класса InetAddress хоста, имя которого ему передано. Если эти методы оказываются не в состоянии получить имя хоста, они передают исключение UnknownHost Except Когда одно имя используется для представления нескольких машин в Интернете — это обычное явление. В мире веб-серверов это единственный путь обеспечения не 6 8 Часть II. Библиотека которой степени масштабируемости. Метод-фабрика getAllByName () возвращает массив класса InetAddress, представляющий все адреса, в которые преобразуется конкретное имя. Он также передает исключение UnknownHost Except ion в случае, если не может преобразовать имя хотя бы в один адрес. Класс InetAddress также включает метод-фабрику getDyAddress () , который принимает адрес и возвращает объект класса InetAddress. Причем могут использоваться как адреса IPv4, таки В следующем примере выводятся адреса и имена локальной машины, а также двух сайтов Интернета Демонстрация применения InetAddress. import java.net.*;class InetAddressTest { public static void main(String args[]) throws UnknownHostException { InetAddress Address = InetAddress.getLocalHost();System.out.println(Address);Address = InetAddress.getByName("www.HerbSchildt.com");System.out.println(Address);InetAddress SW[] = InetAddress.getAllByName("www.nba.c o m "); for (int i=0; i + +) System.out.println(S W [i Ниже показан вывод, созданный этой программой (конечно, код, который вы увидите на своей машине, может несколько отличаться 6.203.115.212 www.HerbSchildt.com/216.92.65.4 www.nba.com/216.66.31.161 Методы экземпляраВ классе InetAddress имеется также несколько других методов, которые могут быть использованы с объектами, возвращенными методами, о которых мы только что говорили. Некоторые из наиболее часто применяемых методов перечислены в табл. Таблица 21.1. Часто используемые методы класса Й в т э д 1.. > : . г . г ; Описание equals(Object другое t A d d r e s s () String g e t H o s t N a m e ()booleani s M u l t i c a s t A d d r e s s () String t o S t r i n g (Возвращает значение true, если объект имеет тот же адрес Интернета, что и другое Возвращает байтовый массив, представляющий 1Р-адрес в порядке байтов сети Возвращает строку, представляющую адрес хоста, ассоциированного с объектом класса InetAddress Возвращает строку, представляющую имя хоста, ассоциированного с объектом класса InetAddress Возвращает значение true, если адрес является групповым, в противном случае возвращает значение false Возвращает строку, включающую имя хоста и адрес для удобства Глава 21. Сеть 6 8 Поиск адресов Интернета осуществляется в серии иерархических кеширован ных служб. Это значит, что ваш локальный компьютер может автоматически соотнести определенное имя сего адресом, как для себя, таки для ближайших серверов. Для всех прочих имен он может обращаться к серверам DNS, откуда получит информацию об адресах. Если такой сервер не имеет информации об определенном адресе, он может обратиться к следующему дистанционному сайту и запросить эту информацию у него. Это может продолжаться вплоть до корневого сервера, и упомянутый процесс может потребовать длительного времени, так что разумно построить структуру вашего кода таким образом, чтобы информация об адресах локально кешировалась и ее не приходилось искать каждый раз заново. Классы lnet4Address и Начиная с версии 1.4 в Java включена поддержка адресов IPv6. В связи с этим были созданы два подкласса класса InetAddress — Inet4Address и Inet 6Address. Класс Inet 4Address представляет традиционные адреса IPv4, а класс Inet6Address инкапсулирует адреса IPv6 нового стиля. Поскольку оба являются подклассами класса InetAddress, ссылки на класс InetAddress могут указывать и на них. Это единственный способ, благодаря которому удалось добавить в Java функциональные возможности IPv6, не нарушая работы существующего кода и не добавляя большого количества новых классов. В большинстве случаев вы просто можете использовать класс InetAddress, работая с адресами, поскольку этот класс приспособлен для обоих стилей. Клиентские сокеты TCP/IP Сокеты T C P /IP применяются для реализации надежных двунаправленных, постоянных соединений между точками — хостами в Интернете на основе потоков. Сокет может использоваться для подключения системы ввода-вывода Java к другим программам, которые могут находиться как на локальной машине, таки на любой другой машине в И нтернете. На заметку Как правило, аплеты могут устанавливать сокетные соединения только стем хостом, с которого они были загружены. Это ограничение введено в связи стем, что было бы опасно для аплетов, загруженных через брандмауэр, иметь доступ к любой произвольной машине. В Java существует два вида сокетов TCP — для серверов и клиентов. Класс Serve г Socket является слушателем, который ожидает подключения клиентов прежде, чем что-либо делать. Другими словами, класс ServerSocket предназначен для серверов. Класс Socket применяется для клиентов. Он разработан так, чтобы соединяться с серверными сокетами и инициировать обмен по протоколу. Поскольку клиентские сокеты наиболее часто применяются в приложениях Java, их мы и рассмотрим здесь. В табл. 21.2 описаны два конструктора, используемые для создания клиентских сокетов. Класс Socket определяет несколько методов экземпляра. Например, класс S o c k e t может быть просмотрен в любое время на предмет извлечения информации об адресе и порте, ассоциированной с ним. Для этого применяются методы, перечисленные в табл. 21.3.
Таблица 21.2. Конструкторы класса S o c k e t6 8 2 Часть II. Библиотека JavaSocket (String имя Хо ста, Создает сокет, подключенный к именованному порт хосту и порту (InetAddress р Адрес, Создает сокет, используя ранее существующий порт объект класса InetAddress и порт Таблица 21.3. Методы экземпляра класса S o c k e t Метод Описание InetAddress g e t l n e t A d d r e s s () int getPort() int g e t L o c a l P o r t (Возвращает объект класса InetAddress, ассоциированный с объектом класса Socket. В случае если сокет не подключен, возвращает значение Возвращает дистанционный порт, к которому подключен вызывающий объект класса Socket. Если сокет не подключен, возвращает значение О Возвращает локальный порт, к которому привязан вызывающий объект класса Socket. Если сокет не привязан, возвращает значение -Вы можете получить доступ к входному и выходному потокам, ассоциированным с классом S o c k e t , с использованием методов g e t I n p u t S t r e a m () и g e t O u p - t u t S t r e a m ( ) , которые описаны в табл. 21.4. Каждый из них может передать исключение I O E x c e p t i o n , если сокет стал недействительным из-за утери соединения. Эти потоки используются точно также, как потоки ввода-вывода, рассмотренные в главе 19, для получения и приема данных. Таблица 21.4. Методы доступа к входному и выходному потокам, связанным с классом S o c k e Метод ____________________ Описание getlnputStream () Возвращает объект класса InetAddress, ассоциированный с вызывающим сокетом <»- OutputStream getOutputStream () Возвращает объект класса OutputStream, ассоциированный с вызывающим сокетом Доступно также еще несколько других методов, включая метод c o n n e c t (), позволяющий задать новое подключение метод is C o n n e c te d ( ), возвращающий значение t r u e , если сокет подключен к серверу метод isB o u n d (), возвращающий значение t r u e , если сокет привязан к адресу и метод i s C l o s e d ( ) , возвращающий значение t r u e , когда сокет закрыт. Чтобы закрыть сокет, вызовите метод c l o s e (). Закрытие сокета приводит к закрытию также связанных с ним потоков ввода-вывода. Начиная с JDK 7 класс S o c k e t реализует также интерфейс A u to C lo s e a b le . Это значит, что для управления сокетом вы можете использовать блок t r y -с-ресурсами. Следующая программа представляет простой пример применения класса S o c k e t . Она открывает соединение спортом (порт 43) на сервере InterNIC, посылает сокету аргументы командной строки, а затем выводит возвращенные данные. Сервер InterNIC пытается трактовать аргумент как зарегистри
Глава 21. Сеть 6 8 3рованное доменное имя Интернета, а затем возвращает адрес и контактную информацию для этого сайта Демонстрация работы с сокетами, import java.net.*; import java.io.*;class Whois {public static void main(String a r g s []) throws Exception { int c;// Создает сокетное соединение спорт Получает входной и выходной потоки in = s .getlnputStream();OutputStream out = s .getOutputStream();// Создать строку запроса str = (args.length == 0 ? "MHProfessional.com" : args[0])+ "\n";// Преобразует в байты byte buff] = s t r .getBytes(); // Посылает запрос out.write(buf); // Читает и отображает ответ while (с = in.readO) != -1) { System.out.print((char) c ) ; } s .c l o s e (Если, к примеру, вы запросите информацию об адресе M H P r o f e s s i o n a l . com, то получите нечто вроде следующего Server Version 2.0 Domain names in the .com and .net domaihs can now be registered with many different competing registrars. Go to http://www.internic.net for detailed information. Domain Name: MHPROFESSIONAL.COM Registrar: MELBOURNE IT, LTD. D/B/A INTERNET NAMES WORLDWIDE Whois Server: whois.melbourneit.com Referral URL: http://www.melbourneit.com Name Server: NS1.MHEDU.COM Name Server: Вот как работает эта программа. Сначала создается объект класса S o c k e t, задающий имя хоста "w h o is . i n t e r n i c . n e t " и номер порта 43 ( i n t e r n i c . n e t — это веб-сайт InterNIC, обрабатывающий запросы whois; порт 43 предназйачен именно для этой службы. Затем и входной, и выходной потоки открываются в со кете. Далее создается строка, содержащая имя веб-сайта, информацию о котором вы хотите получить. В данном случае, если никакой сайт не указан в командной
|