Платформа J2Me
Шрифт:
StreamConnection conn =
Connector.open("socket://server.foo.com:98765");
Клиенты должны включать имя сервера, поддерживающего службу; номер порта представляет известный сокет сервера. Клиенты, которые хотят соединиться со службой на локальной машине, могут использовать обозначение localhost для сервера, как показано в следующем вызове:
StreamConnection conn =
Connector.open("socket://localhost:98765");
Оба вызова StreamConnectionNotifier.acceptAndOpen(} сервера и Connector.open клиента создают объект StreamConnection. Вы уже видели класс StreamConnection при нашем обсуждении коммуникационных портов.
Вы
Нигде не оговаривается, какие виды протоколов может представлять интерфейс StreamConnection. Интерфейс извлекает подробную информацию о реализации протокола из приложения. Приложения не осведомлены о платформно-определяемых классах, которые реализуют интерфейсы. Хотя реализации интерфейса структуры общих соединений могут варьироваться, они должны поддерживать указанное поведение и семантику интерфейса.
Важно заметить, что не все реализации поддерживают серверные сокеты. И, из тех, что делают это, некоторые в настоящее время работают не совсем правильно. Если поддержка серверных сокетов недоступна на вашей реализации, но вы по некоторой причине должны использовать сокеты, вам придется разработать схему, по которой клиент сможет соединяться с «сервером». Сервер не сможет поддерживать модель известного сокета, ему придется определить другую модель, которая позволит клиентам получить средство установления соединения.
В листингах 8.6–8.8 демонстрируется набор классов, которые составляют структуру сокетных коммуникаций в MIDP. Смысл заключается в том, что эти классы будут использоваться приложением, которое нуждается в сокетных коммуникациях. Эти примеры составляют не больше чем основу, которая формирует базовую структуру поддержки сокетных взаимодействий. Они не являются функционирующими приложениями.
Некоторые данные были проигнорированы в этом коде. Например, сама сетевая служба не определена, нет определения синтаксиса или семантики сообщения протокола уровня приложений. Кроме того, код не обращается к очистке рабочих нитей со стороны сервера. Следующие классы являются классами, составляющими данный пример:
— ServerSocket — определяет демон сервера, который прослушивает известный сокет на предмет клиентских запросов соединения.
— Server Agent — определяет объект, один экземпляр которого демон создает для каждого клиентского запроса. Каждый экземпляр взаимодействует с клиентом. Данный класс определяет действительную службу.
— ClientSocket — представляет клиента.
Листинг 8.6. Сервер порождает новую нить для создания объекта со стороны сервера, который взаимодействует с каждым клиентом. Клиент и сервер должны определять семантику своих сообщений
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import Java.io.lOException;
/**
Данный класс реализует службу, которая прослушивает запросы клиентских соединений на известном сокете.
Он открывает соединение на предварительно определенном номере порта.
А затем блокирует обработку на данном порте, ожидая клиентского запроса соединения.
Когда запрос появляется, он принимает его и открывает новое соединение сокета. Эти два этапа выражаются в реализации, уведомляющей реализацию клиента о новом соединении сокета.
Этот сервер затем порождает компонент и передает его новому объекту соединения. Компонент запускает отдельную нить. Компонент теперь свободен для взаимодействия
с клиентом асинхронно от продолжающейся работы сервера.public class ServerSocket imlements Runnable
{
// Порт по умолчанию, на котором установлен известный
// сокет. public static final String DEFAULT_PORT = «9876»;
// Порт, на котором установлен известный
// сокет. protected String wellKnownPort;
// URI, который данный сервер использует для открытия своего
// известного сокета. protected String uri;
// Соединение с известным сокетом.
protected StreamConnectionNotifier wellKnownConn;
// Соединение сокета, которое соединяется с клиентом,
protected StreamConnection clientConn;
/**
Конструктор для подклассов.
*/
protected ServerSocket
super ;
/**
Конструктор.
@param port Известный порт, на котором устанавливается этот объект как блок прослушивания.
*/
public ServerSocket (String port)
}
thisl); if (port == null)
{
wellKnownPort = DEFAULT_PORT;
}
else
}
wellKnownPort = port;
}
setURI(port);
{
protected void setURI(String port)
{
StringBuffer buf = new StringBuffer("socket://:");
buf.append(port); uri = buf.toString;
}
/**
Запустите данный сервер. Этот метод должен бытьвызван явно после создания данного объекта. Он запускает прослушивание запросов клиентов на известном сокете.
Оператор вызова должен запустить это выполнение в отдельной нити.
*/
public void run
{
while (true)
{
try
{
// Откройте соединение известного сокета для данной
// «службы». wellKnownConn = (StreamConnectionNotifier)
Connector.open(uri);
//Прослушиваем запросы соединения. Данный вызов
// блокирует работу до тех пор, пока не будет получен
// запрос на соединение.
clientConn = wellKnownConn.acceptAndOpen
// Создадим экземпляр агента» сервера, объект, который
// представляет службу для клиента. Каждый экземпляр
// взаимодействует с одним клиентом.
// Порождаем нить для взаимодействия с
// клиентом, создавшим запрос на соединение.
ServerAgent agent = new ServerAgent(clientConn);
Thread thread = new Thread (agent);
} catch (lOException ioe)
(System.out.printlnfioe.getMessage!));
ioe.printStackTrace; break;
)
}
}
}
Листинг 8.7. Агент сервера является объектом, который взаимодействует с клиентом независимо от демона сервера. Он запускает свою собственную нить, позволяя другим экземплярам одновременно взаимодействовать со своими клиентами
import javax.microedition. io._StreamConnectior.;
/**
Данный класс определяет компоненту, которую сервер создает для взаимодействия с клиентом.
Он действует как «агент» от имени сервера для того, чтобы сервер был свободен для прослушивания только новых запросов соединения.
Экземпляры данного класса являются частью сервера.
*/
public class ServerAgent implements Runnable
private StreamConnection conn;
/**
Конструктор.
@param с Объект соединения, который представляет
соединение с клиентом. Класс ServerSocket создает и пересылает
его в данный конструктор.
*/
public ServerAgent(StreamConnection c)
super ; conn = с;
}
/**