Spec-Zone .ru
спецификации, руководства, описания, API
|
Пример, которым обладают в этом разделе, состоит из двух приложений: клиент и сервер. Сервер непрерывно получает пакеты дейтаграммы по сокету дейтаграммы. Каждый пакет дейтаграммы, полученный сервером, указывает на клиентский запрос на цитату. Когда сервер получает дейтаграмму, он отвечает, отправляя пакет дейтаграммы, который содержит короткую "кавычку момента" назад клиенту.
Клиентское приложение в этом примере довольно просто. Это отправляет единственный пакет дейтаграммы серверу, указывающему, что клиент хотел бы получить кавычку момента. Клиент тогда ожидает сервера, чтобы отправить пакет дейтаграммы в ответе.
Два класса реализуют серверное приложение: QuoteServer
и QuoteServerThread
. Единственный class реализует клиентское приложение: QuoteClient
.
Давайте исследуем эти классы, запускающиеся с class, который содержит main
метод для серверного приложения. Работа С Серверным Приложением содержит версию апплета QuoteClient
class.
QuoteServer
class, показанный здесь полностью, содержит единственный метод: main
метод для серверного приложения кавычки. main
метод просто создает новое QuoteServerThread
возразите и запускает это:
import java.io.*; public class QuoteServer { public static void main(String[] args) throws IOException { new QuoteServerThread().start(); } }
QuoteServerThread
class реализует основную логику сервера кавычки.
QuoteServerThread
КлассКогда создающийся, QuoteServerThread
создает a DatagramSocket
на порту 4445 (произвольно выбранный). Это DatagramSocket
через который сервер связывается со всеми его клиентами.
public QuoteServerThread() throws IOException { this("QuoteServer"); } public QuoteServerThread(String name) throws IOException { super(name); socket = new DatagramSocket(4445); try { in = new BufferedReader(new FileReader("one-liners.txt")); } catch (FileNotFoundException e){ System.err.println("Couldn't open quote file. Serving time instead."); } }
Помните, что определенные порты выделяются известным службам, и невозможно использовать их. Если Вы определяете порт, который используется, создание DatagramSocket
перестанет работать.
Конструктор также открывает a BufferedReader
на названном файле one-liners.txt
который содержит список кавычек. Каждая кавычка в файле находится на строке отдельно.
Теперь для интересной части QuoteServerThread
: run
метод. run
переопределения метода run
в Thread
class и обеспечивает реализацию для потока. Для получения информации о потоках см. Определение и Запуск Потока.
run
метод содержит a while
цикл, который продолжается пока, есть больше кавычек в файле. Во время каждой итерации цикла поток ожидает a DatagramPacket
прибыть по DatagramSocket
. Пакет указывает на запрос от клиента. В ответ на запрос клиента, QuoteServerThread
получает кавычку от файла, помещает это в a DatagramPacket
и отправляет это по DatagramSocket
клиенту, который попросил это.
Давайте смотреть сначала на раздел, который получает запросы от клиентов:
byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet);
Первый оператор создает массив байтов, который тогда используется, чтобы создать a DatagramPacket
. DatagramPacket
будет использоваться, чтобы получить дейтаграмму от сокета из-за конструктора, используемого, чтобы создать это. Этот конструктор требует только двух параметров: байтовый массив, который содержит специфичные для клиента данные и длину байтового массива. Создавая a DatagramPacket
передаться по DatagramSocket
, также следует предоставить Интернет-адрес и номер порта места назначения пакета. Вы будете видеть это позже, когда мы обсудим, как сервер отвечает на клиентский запрос.
Последний оператор в предыдущем фрагменте кода получает дейтаграмму от сокета (информация, полученная от клиента, копируется в пакет). Получить метод ожидает навсегда, пока пакет не получается. Если никакой пакет не получается, сервер не делает дальнейших успехов и только ожидает.
Теперь предположите, что, сервер получил запрос от клиента для кавычки. Теперь сервер должен ответить. Этот раздел кода в методе выполнения создает ответ:
String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes();
Если файл кавычки не становился открытым по некоторым причинам, то in
равняется нулю. Если это верно, сервер кавычки подает время суток вместо этого. Иначе, сервер кавычки получает следующую кавычку от уже открытого файла. Наконец, код преобразовывает строку в массив байтов.
Теперь, run
метод отправляет ответ клиенту по DatagramSocket
с этим кодом:
InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet);
Первые два оператора в этом сегменте кода получают Интернет-адрес и номер порта, соответственно, от пакета дейтаграммы, полученного от клиента. Интернет-адрес и номер порта указывают, куда пакет дейтаграммы прибыл из. Это - то, куда сервер должен отправить свой ответ. В этом примере байтовый массив пакета дейтаграммы не содержит релевантной информации. Прибытие самого пакета указывает на запрос от клиента, который может быть найден в Интернет-адресе и номере порта, обозначенном в пакете дейтаграммы.
Третий оператор создает новое DatagramPacket
объект, предназначенный для того, чтобы отправить сообщение дейтаграммы по сокету дейтаграммы. Можно сказать что новое DatagramPacket
предназначается, чтобы отправить данные по сокету из-за конструктора, используемого, чтобы создать это. Этот конструктор требует четырех параметров. Первыми двумя параметрами является то же самое, требуемое конструктором, используемым, чтобы создать дейтаграммы получения: байтовый массив, содержащий сообщение с отправителя на получатель и длину этого массива. Следующие два параметра отличаются: Интернет-адрес и номер порта. Эти два параметра являются полным адресом места назначения пакета дейтаграммы и должны быть предоставлены отправителем дейтаграммы. Последняя строка кода передается DatagramPacket
продвигающийся.
Когда сервер считал все кавычки из файла кавычки, while
цикл завершается и run
метод очищает:
socket.close();
QuoteClient
class реализует клиентское приложение для QuoteServer
. Это приложение отправляет запрос QuoteServer
, ожидает ответа, и, когда ответ получается, дисплеи он к стандартному выводу. Давайте смотреть на код подробно.
QuoteClient
class содержит один метод, main
метод для клиентского приложения. Вершина main
метод объявляет несколько локальных переменных для своего использования:
int port; InetAddress address; DatagramSocket socket = null; DatagramPacket packet; byte[] sendBuf = new byte[256];
Во-первых, main
метод обрабатывает параметры командной строки, используемые, чтобы вызвать QuoteClient
приложение:
if (args.length != 1) { System.out.println("Usage: java QuoteClient <hostname>"); return; }
QuoteClient
приложение требует параметров командной строки: имя то, машины, на который QuoteServer
работает.
Затем, main
метод создает a DatagramSocket
:
DatagramSocket socket = new DatagramSocket();
Клиент использует конструктора, который не требует номера порта. Этот конструктор только связывает DatagramSocket
к любому доступному локальному порту. Не имеет значения, какой порт клиент связывается с потому что DatagramPacket
s содержат адресную информацию. Сервер получает номер порта от DatagramPacket
s и отправляют его ответ на тот порт.
Затем, QuoteClient
программа отправляет запрос серверу:
byte[] buf = new byte[256]; InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet);
Сегмент кода получает Интернет-адрес для узла, названного на командной строке (по-видимому имя машины, на которой сервер работает). Это InetAddress
и номер порта 4445 (номер порта, что сервер, используемый, чтобы создать DatagramSocket
) тогда используются, чтобы создать DatagramPacket
предназначенный для того Интернет-адреса и номера порта. Поэтому DatagramPacket
будет поставлен серверу кавычки.
Отметьте, что код создает a DatagramPacket
с пустым байтовым массивом. Байтовый массив пуст, потому что этот пакет дейтаграммы является просто запросом к серверу для информации. Весь сервер должен знать, чтобы отправить ответ - адрес и номер порта, к которому ответ - является автоматически частью пакета.
Затем, клиент получает ответ от сервера и выводит на экран его:
packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData(), 0, packet.getLength()); System.out.println("Quote of the Moment: " + received);
Чтобы получить ответ от сервера, клиент создает "получить" пакет и использует DatagramSocket
получите метод, чтобы получить ответ от сервера. Получить метод ожидает, пока пакет дейтаграммы, предназначенный для клиента, не проникает через сокет. Отметьте, что, если ответ сервера так или иначе теряется, клиент будет ожидать навсегда из-за политики без гарантии модели дейтаграммы. Обычно, клиент устанавливает таймер так, чтобы он не ожидал навсегда ответа; если никакой ответ не прибывает, таймер уходит, и клиент ретранслирует.
Когда клиент получает ответ от сервера, клиент использует getData метод, чтобы получить те данные от пакета. Клиент тогда преобразовывает данные в строку и выводит на экран их.
После того, как Вы успешно скомпилировали сервер и клиентские программы, Вы выполняете их. Необходимо выполнить программу сервера сначала. Только используйте интерпретатор Java и определите QuoteServer
Имя class.
Как только сервер запустился, можно выполнить клиентскую программу. Не забудьте выполнять клиентскую программу с одним параметром командной строки: имя то, узла, на который QuoteServer
работает.
После того, как клиент отправляет запрос и получает ответ от сервера, следует видеть вывод, подобный этому:
Quote of the Moment: Good programming is 99% sweat and 1% coffee.