|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Http://www.bsu.by
URI не может содержать такие специальные символы, как пробелы, табуляции, возврат каретки. Их можно задавать через шестнадцатеричные коды. Например: %20 обозначает пробел. Другие зарезервированные символы: символ & –разделитель аргументов, символ? –следует перед аргументами запросов, символ + – пробел, символ # – ссылки внутри страницы (имя_страницы#имя_ссылки). Определить IP-адрес в приложеннии можно с помощью объекта класса InetAddress из пакета java.net. Класс InetAddress не имеет public -конструкторов. Создать объект класса можно с помощью статических методов. Метод getLocalHost() возвращает объект класса InetAddress, содержащий IP-адрес и имя компьютера, на котором выполняется программа. Метод getByName(String host) возвращает объект класса InetAddress, содержащий IP-адрес по имени компьютера, используя пространство имен DNS. IP-адрес может быть временным, различным для каждого соединения, однако он остается постоянным, если соединение установлено. Метод getByAddress(byte[] addr) создает объект класса InetAddress, содержащий имя компьютера, по IP-адресу, представленному в виде массива байт. Если компьютер имеет несколько IP, то получить их можно методом getAllByName(String host),возвращающим массив объектов класса InetAddress. Если IP для данной машины один, то массив будет содержать один элемент. Метод getByAddress(String host, byte[] addr) создает объект класса InetAddress с заданным именем и IP-адресом, не проверяя существование такого компьютера. Все эти методы являются потенциальными генераторами исключительной ситуации UnknownHostException, и поэтому их вызов должен быть обработан с помощью throws для метода или блока try-catch. Проверить доступ к компьютеру в данный момент можно с помощью метода boolean isReachable(int timeout), который возвращает true, если компьютер доступен, где timeout – время ожидания ответа от компьютера в миллисекундах. Следующая программа демонстрирует при наличии Internet-соединения, как получить IP-адрес текущего компьютера и IP-адрес из имени домена с помощью сервера имен доменов (DNS), к которому обращается метод getByName() класса InetAddress. /* пример # 1: вывод IP-адреса компьютера и интернет-ресурса: InetLogic.java*/ package chapt15; import java.net.*;
public class InetLogic { public static void main(String[] args) { InetAddress myIP = null; InetAddress bsuIP = null; try { myIP = InetAddress.getLocalHost(); // вывод IP-адреса локального компьютера System.out.println("Мой IP -> " + myIP.getHostAddress()); bsuIP = InetAddress.getByName( "www.bsu.by"); // вывод IP-адреса БГУ www.bsu.by System.out.println("BSU -> " + ibaIP.getHostAddress()); } catch (UnknownHostException e) { // если не удается найти IP e.printStackTrace(); } } } В результате будет выведено, например: Мой IP -> 172.17.16.14 BSU -> 217.21.43.10 Метод getLocalHost() класса InetAddress создает объект myIP и возвращает IP-адрес компьютера. /* пример # 2: присваивание фиктивного имени реальному ресурсу, заданному через IP: UnCheckedHost.java */ package chapt15; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException;
public class UnCheckedHost { public static void main(String[] args) { // задание IP-адреса лаборатории bsu.iba.by в виде массива byte ip[] ={(byte)217, (byte)21, (byte)43, (byte)10}; try { InetAddress addr = InetAddress.getByAddress("University", ip); System. out. println(addr.getHostName() + "-> cоединение:" + addr.isReachable(1000)); } catch (UnknownHostException e) { System. out. println("адрес недоступен"); e.printStackTrace(); } catch (IOException e) { System. out. println("ошибка потока"); e.printStackTrace(); } } } В результате будет выведено в случае подключения к сети Интернет: University-> cоединение:true Для доступа к ресурсам можно создать объект класса URL, указывающий на ресурсы в Internet. В следующем примере объект URL используется для доступа к HTML-файлу, на который он указывает, и отображает его в окне браузера с помощью метода showDocument(). /* пример # 3: запуск страницы из апплета: MyShowDocument.java */ package chapt15; import java.awt.Graphics; import java.net.MalformedURLException; import java.net.URL; import javax.swing.JApplet;
public class MyShowDocument extends JApplet { private URL bsu = null;
public String getMyURL() { return "http://www.bsu.by"; } public void paint(Graphics g) { int timer = 0; g.drawString("Загрузка страницы", 10, 10); try { for (; timer < 30; timer++) { g.drawString(".", 10 + timer * 5, 25); Thread. sleep (100); } bsu = new URL(getMyURL()); getAppletContext().showDocument(bsu, "_blank"); } catch (InterruptedException e) { e.printStackTrace(); } catch (MalformedURLException e) { // некорректно задан протокол, доменное имя или путь к файлу e.printStackTrace(); } } } Метод showDocument() может содержать параметры для отображения страницы различными способами: “ _self ” – выводит документ в текущий фрейм, “ _blank ” – в новое окно, “ _top ” – на все окно, “ _parent ” – в родительском окне, “ имя_окна ” – в окне с указанным именем. Для корректной работы данного примера апплет следует запускать из браузера, используя следующий HTML-документ: <html> <body align=center> <applet code=chapt15.MyShowDocument.class></applet> </body></html> В следующей программе читается содержимое HTML-файла по указанному адресу и выводится в окно консоли. /* пример # 4: чтение документа из интернета: ReadDocument.java */ package chapt15; import java.net.*; import java.io.*;
public class ReadDocument { public static void main(String[] args) { try { URL lab = new URL("http://www.bsu.by"); InputStreamReader isr = new InputStreamReader(lab.openStream()); BufferedReader d = new BufferedReader(isr); String line = ""; while ((line = d.readLine())!= null) { System.out.println(line); } } catch (MalformedURLException e) { // некорректно заданы протокол, доменное имя или путь к файлу e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } Сокетные соединения по протоколу TCP/IP Сокеты (сетевые разъёмы) - это логическое понятие, соответствующее разъёмам, к которым подключены сетевые компьютеры и через которые осуществляяется двунаправленная поточная передача данных между компьютерами. Сокет определяется номером порта и IP-адресом. При этом IP-адрес используется для идентификации компьютера, номер порта – для идентификации процесса, работающего на компьютере. Когда одно приложение знает сокет другого, создается сокетное протоколо-ориентированное соединение по протоколу TCP/IP. Клиент пытается соединиться с сервером, инициализируя сокетное соединение. Сервер прослушивает сообщение и ждет, пока клиент не свяжется с ним. Первое сообщение, посылаемое клиентом на сервер, содержит сокет клиента. Сервер, в свою очередь, создает сокет, который будет использоваться для связи с клиентом, и посылает его клиенту с первым сообщением. После этого устанавливается коммуникационное соединение. Сокетное соединение с сервером создается клиентом с помощью объекта класса Socket. При этом указывается IP-адрес сервера и номер порта. Если указано символьное имя домена, то Java преобразует его с помощью DNS-сервера к IP-адресу. Например, если сервер установлен на этом же компьютере, соединение с сервером можно установить из приложения клиента с помощью инструкции: Socket socket = new Socket(" ИМЯ_СЕРВЕРА ", 8030); Сервер ожидает сообщения клиента и должен быть заранее запущен с указанием определенного порта. Объект класса ServerSocket создается с указанием конструктору номера порта и ожидает сообщения клиента с помощью метода accept() класса ServerSocket, который возвращает сокет клиента: ServerSocket server = new ServerSocket(8030); Socket socket = server.accept(); Таким образом, для установки необходимо установить IP-адрес и номер порта сервера, IP-адрес и номер порта клиента. Обычно порт клиента и сервера устанавливаются одинаковыми. Клиент и сервер после установления сокетного соединения могут получать данные из потока ввода и записывать данные в поток вывода с помощью методов getInputStrеam() и getOutputStrеam() или к PrintStream для того, чтобы программа могла трактовать поток как выходные файлы. В следующем примере для отправки клиенту строки "привет!" сервер вызывает метод getOutputStream() класса Socket. Клиент получает данные от сервера с помощью метода getInputStream(). Для разъединения клиента и сервера после завершения работы сокет закрывается с помощью метода close() класса Socket. В данном примере сервер отправляет клиенту строку "привет!", после чего разрывает связь. /* пример # 5: передача клиенту строки: MyServerSocket.java */ package chapt15; import java.io.*; import java.net.*; public class MyServerSocket { public static void main(String[] args) { Socket s = null; try { // отправка строки клиенту //создание объекта и назначение номера порта ServerSocket server = new ServerSocket(8030); s = server.accept(); //ожидание соединения PrintStream ps = new PrintStream(s.getOutputStream()); // помещение строки "привет!" в буфер ps.println("привет!"); // отправка содержимого буфера клиенту и его очищение ps.flush(); ps.close(); } catch (IOException e) { System. err. println("Ошибка: " + e); } finally { if (s!= null) s.close(); // разрыв соединения } } } /* пример # 6: получение клиентом строки: MyClientSocket.java */ package chapt15; import java.io.*; import java.net.*; public class MyClientSocket { public static void main(String[] args) { Socket socket = null; try { // получение строки клиентом socket = new Socket(" ИМЯ_СЕРВЕРА ", 8030); /* здесь "ИМЯ_СЕРВЕРА" компьютер, на котором стоит сервер-сокет"*/ BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream())); String msg = br.readLine(); System. out. println(msg); socket.close(); } catch (IOException e) { System. err. println("ошибка: " + e); } } } Аналогично клиент может послать данные серверу через поток вывода, полученный с помощью метода getOutputStream(), а сервер может получать данные через поток ввода, полученный с помощью метода getInputStream(). Если необходимо протестировать подобный пример на одном компьютере, можно выступать одновременно в роли клиента и сервера, используя статические методы getLocalHost() класса InetAddress для получения динамического IP-адреса компьютера, который выделяется при входе в сеть интернет. Многопоточность Сервер должен поддерживать многопоточность, иначе он будет не в состоянии обрабатывать несколько соединений одновременно. В этом случае сервер содержит цикл, ожидающий нового клиентского соединения. Каждый раз, когда клиент просит соединения, сервер создает новый поток. В следующем примере создается класс ServerThread, расширяющий класс Thread, и используется затем для соединений с многими клиентами, каждый в своем потоке. /* пример # 7: сервер для множества клиентов: NetServerThread.java */ package chapt15; import java.io.*; import java.net.*;
public class NetServerThread { public static void main(String[] args) { try { ServerSocket serv = new ServerSocket(8071); System. out. println("initialized"); while (true) { //ожидание клиента Socket sock = serv.accept(); System. out. println( sock.getInetAddress().getHostName() + " connected"); /*создание отдельного потока для обмена данными с соединившимся клиентом*/ ServerThread server = new ServerThread(sock); server.start(); //запуск потока } } catch (IOException e) { System. err. println(e); } } } class ServerThread extends Thread { private PrintStream os; //передача private BufferedReader is; //чтение private InetAddress addr; //адрес клиента
public ServerThread(Socket s) throws IOException { os = new PrintStream(s.getOutputStream()); is = new BufferedReader( new InputStreamReader( s.getInputStream())); addr = s.getInetAddress(); } public void run() { int i = 0; String str; try { while ((str = is.readLine())!= null) { if ("PING".equals(str)) os.println("PONG "+ ++i); System. out. println("PING-PONG" + i + " with " + addr.getHostName()); } } catch (IOException e) { //если клиент не отвечает, соединение с ним разрывается System. out. println("Disconnect"); } finally { disconnect(); //уничтожение потока } } public void disconnect() { try { System. out. println(addr.getHostName() + " disconnected"); os.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } finally { this. interrupt(); } } } Сервер передает сообщение, посылаемое клиенту. Для клиентских приложений поддержка многопоточности также необходима. Например, один поток ожидает выполнения операции ввода/вывода, а другие потоки выполняют свои функции. /* пример # 8: получение и отправка сообщения клиентом в потоке: NetClientThread.java */ package chapt15; import java.io.*; import java.net.*;
public class NetClientThread { public static void main(String[] args) { try { // установка соединения с сервером Socket s = new Socket(InetAddress. getLocalHost (), 8071); //или Socket s = new Socket("ИМЯ_СЕРВЕРА", 8071); PrintStream ps = new PrintStream(s.getOutputStream()); BufferedReader br = new BufferedReader( new InputStreamReader(s.getInputStream())); for (int i = 1; i <= 10; i++) { ps.println("PING"); System. out. println(br.readLine()); Thread. sleep (1000); } s.close(); } catch (UnknownHostException e) { // если не удалось соединиться с сервером System. out. println("адрес недоступен"); e.printStackTrace(); } catch (IOException e) { System. out. println("ошибка I/О потока"); e.printStackTrace(); } catch (InterruptedException e) { System. out. println( "ошибка потока выполнения"); e.printStackTrace(); } } } Сервер должен быть инициализирован до того, как клиент попытается осуществить сокетное соединение. При этом может быть использован IP-адрес локального компьютера. Датаграммы и протокол UDP UDP (User Datagram Protocol) не устанавливает виртуального соединения и не гарантирует доставку данных. Отправитель просто посылает пакеты по указанному адресу; если отосланная информация была повреждена или вообще не дошла, отправитель об этом даже не узнает. Однако достоинством UDP является высокая скорость передачи данных. Данный протокол часто используется при трансляции аудио- и видеосигналов, где потеря небольшого количества данных не может привести к серьезным искажениям всей информации. По протоколу UDP данные передаются пакетами. Пакетом в этом случае UDP является объект класса DatagramPacket. Этот класс содержит в себе передаваемые данные, представленные в виде массива байт. Конструкторы класса: DatagramPacket(byte[] buf, int length) DatagramPacket(byte[] buf, int length, Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.031 сек.) |