Чтобы использовать дейтаграммное соединение, приложение-клиент выполняет следующие шаги:
1. Оно создает объект DatagramConnection.
2. Получает объект Datagram из объекта DatagramConnection.
3. Затем оно заполняет объект Datagram данными, составляющими полезную нагрузку, которая будет послана принимающему объекту.
4. Запрашивает соединение о посылке дейтаграммы.
5. Запрашивает соединение о получении ответной дейтаграммы.
Чтобы создать дейтаграммное соединение, вам все равно нужно использовать класс Connector. Вы указываете, что желаете получить дейтаграммное соединение, поставляя строковую дейтаграмму в поле схемы URI, который вы передаете одной или трем формам метода Connector.open(). Полный синтаксис дейтаграммных адресов следующий:
address:= <протокол>://<адресат>
protocol:= «datagram»
target:= [<хост>]:<порт>
host:= Значимое DNS-имя хоста или его номер>
port:= Значимуй системный номер порта>
Указание полей хоста необязательно. Если вы пропускаете поле хоста, соединение представляет соединение сервера — реализация допускает, что объект, запрашивающий соединение, является сервером. Серверы не инициируют передачу сообщений, так что для указания места назначения имя хоста не требуется. Соединение сервера ожидает клиента для посылки ему дейтаграммы. Сервер извлекает адрес посылающего из дейтаграммы, полученной им, и использует его для ответа. Пример указания соединения сервера:
datagram:/7:513
Если поле хоста указано, соединение открывается как соединение клиента. Реализация предполагает, что запрашивающий является клиентом, который инициирует соединение, поскольку он желает послать дейтаграмму адресованному узлу. Пример соединения клиента, указывающего известный компьютер:
datagram://server.foo.com:513
Когда соединение установлено, ваше приложение может использовать его для отправки и получения дейтаграмм. Интерфейс javax.microedition.io.Datagram определяет дейтаграммы, которые являются частями сообщения, посланными и полученными протоколами передачи дейтаграмм. Объект DatagramConnection посылает и получает объекты Datagram. Обратите внимание, что методы, указанные в таблице 8.9, содержат несколько ссылок на тип Datagram.
В таблице 8.10 перечислены методы интерфейса Datagram. Обратите внимание, что они отражают только следующие понятия:
— адрес — представляет адрес посылающего или принимающего объекта;
— полезная нагрузка — дейтаграмма рассматривает данные как один непрозрачный объект без интерпретации его формы, структуры или типа.
Это минимальная информация, требуемая всеми пакетами. Все дейтаграммы должны устанавливать эту информацию для того, чтобы пересылка прошла успешно.
В интерфейсе Datagram отсутствует информация о синтаксисе или семантике полезной нагрузки. Причина этого заключается всего лишь в том, что дейтаграммы не определяют синтаксиса или семантики данных, которые они переносят. Дейтаграммы просто рассматривают свою полезную нагрузку как последовательность байтов. Полезная нагрузка дейтаграммы определяется просто как byte [].
Дейтаграмма может содержать любую информацию. Дейтаграммная служба определяет формат и содержимое ее дейтаграмм. Посылающее и получающее устройства должны создавать дейтаграммы таким образом, чтобы они придерживались этих определений. То есть byte [] должен быть правильно написан посылающим и правильно проанализирован принимающим устройством.
Интерфейс Datagram происходит из интерфейсов Datalnput и DataOutput в пакете java.io. Такое происхождение гарантирует наличие удобного интерфейса для чтения двоичных данных из дейтаграммы и записи в нее. На рисунке 8.4 показана иерархия происхождения интерфейса Datagram. В таблице 8.11 перечислены методы интерфейса Datalnput, а в таблице 8.12 перечислены методы интерфейса DataOutput. Эти интерфейсы идентичны интерфейсам пакета java.io J2SE.
Рисунок 8.4. Дейтаграмма определяет общие данные. Методы в этой иерархии интерфейсов поддерживают только низшую абстракцию, которая дает возможность манипулировать встроенными типами данных. Для полей, определяемых протоколом, абстракции не существует
Таблица 8.10. Методы интерфейса Datagram
Название метода интерфейса Datagram — Описание
String getAddress() — Выдает адрес в данной дейтаграмме
byte [] getData() — Выдает буфер, содержащий полезную нагрузку дейтаграмм
int getLength() — Выдает длину полезной нагрузки дейтаграммы
int getOffset() — Выдает смещение указателя для чтения/записи в буфере полезной нагрузки
void reset() — Восстанавливает позицию указателя для чтения/записи в буфере полезной нагрузки
void setAddress (Datagram reference) — Устанавливает, что адрес данной дейтаграммы является адресом указанной дейтаграммы
void setAddress (String addr) — Устанавливает адрес, указываемый строкой
void setData (byte[] buffer, int offset, int len) — Устанавливает полезную нагрузку данной дейтаграммы
void setLength (int len) — Устанавливает длину полезной нагрузки дейтаграммы
В дополнение к согласованию формата, посылающее и принимающее устройства должны быть способны определять местонахождение друг друга. Каждая служба имеет связь со стандартным портом. Эта связь гарантирует, что клиент знает, как установить соединение с сервером, который предоставляет желаемую службу.
Таблица 8.11. Методы интерфейса Datalnput
Название метода Datalnput — Описание
boolean readBoolean() — Считывает только значение Boolean из входного потока
byte readByte() — Считывает один байт из входного потока
char readChar() — Считывает символ из входного потока
void readFully (byte [] b) — Считывает байты из входного потока, пока указанный массив не наполнится
void readFully(byte[] b, int off, int len) — Считывает указанное число байт в указанный буфер, начиная с указанного сдвига
int readlnt() — Считывает значение int из входного потока
long readLong() — Считывает значение long из входного потока
short readShort() — Считывает два входных байта и выдает значение short
int readUnsignedByte() — Считывает один байт, дополненный нулями, из потока
int readUnsignedShort() — Считывает два входных байта и выдает значение int
String readUTF() — Считывает в UTF-8 шифрованную строку символов
int skipBytes (int n) — Просматривает n байтов из входного потока
Таблица 8.12. Методы интерфейса DataOutput
Название метода DataOutput — Описание
void writeByte (byte [] b) — Записывает все байты в выходной поток
void write (byte[] b, int off, int len) — Записывает указанное число байтов в выходной поток, начиная от смещения
void write (int b) — Записывает младший байт в выходной поток
void writeBoolean (boolean v) — Записывает значение boolean
void writeByte (int v) — Записывает младший байт int
void writeChar (int c) — Записывает два младших байта в выходной поток
void writeChars (String s) — Записывает каждый символ в уникоде в выходной поток
void writelnt(int v) — Записывает int (четыре байта) в выходной поток
void writeLong (long v) — Записывает значение long (четыре байта) в выходной поток
void writeShort (int v) — Записывает int как два байта в выходной поток
void writeUTF(String s) — Записывает каждый символ в формате Java LJTF, которому предшествуют два байта, показывающие длину в байтах