с использованием механизма сокетов

advertisement
Лекция N3. Реализация архитектуры «Клиент-сервер» с использованием механизма сокетов
Сокет – это описатель сетевого соединения с другими приложениями. С помощью сокетов
программист может разрабатывать свои протоколы для обмена информацией между сервером и клиентом.
Для создания сокета необходимо:




IP-адрес локальной машины (клиента)
Номер порта TCP, который использует приложение на локальной машине (на машине
клиента)
IP-адрес машины с которой устанавливается соединение (сервер)
Номер порта TCP, на который отзывается приложение, ожидающее установления связи (на стороне сервера)
Схема взаимодействия сервера и клиента
Обзор сокетов
Библиотека Winsock поддерживает два вида сокетов - синхронные (блокируемые) и асинхронные (неблокируемые). Синхронные сокеты задерживают управление на время выполнения операции, а асинхронные возвращают его немедленно, продолжая выполнение в фоновом режиме, и, закончив работу, уведомляют об этом вызывающий код.
Независимо от вида, сокеты делятся на два типа - потоковые и дейтаграммные. Потоковые
сокеты работают с установкой соединения, обеспечивая надежную идентификацию обоих
сторон и гарантируют целостность и успешность доставки данных. Дейтаграмные сокеты
работают без установки соединения и не обеспечивают ни идентификации отправителя, ни
контроля успешности доставки данных, зато они заметно быстрее потоковых.
Выбор того или иного типа сокетов определяется транспортным протоколом на котором работает сервер, - клиент не может по своему желанию установить с дейтаграммным сервером
потоковое соединение.
Замечание: дейтаграммные сокеты опираются на протокол UDP, а потоковые на TCP.
Принципы применения сокетов
При создании сокета, указывается в какой области происходит работа: UNIX (AF_UNIX),
TCP/IP (AF_INET), X25, DECNET, APPLETALK... Каждой области соответствует свой тип
протокола. Кроме того, задается тип, определяющий свойства коммуникации:
- SOCK_DGRAM: сообщения посылаются в форме дейтаграмм. Связанный с ним протокол
связи нe является таким надежным (нарушается последовательность, возможны потери данных) в реэиме без установления логического соединения, как UDP в области AF_INET;
- SOCK_STREAM: посылаются потоки байтов, понятие "сообщения" не вводится. Используемый протокол связи надежен, с установлением виртуального соединения, как TCP в области
AF_INET;
- SOCK_ RAW: обеспечивает доступ к протоколам самого низкого уровня, таким как IP в области AF_INET, либо реализует новые протоколы.
Если используются сокеты над UDP размер передаваемых данных ограничен несколькими
килобайтами, от 2 Кб до 8 Кб, в зависи-мости от системы. Сокет-интерфейс можно использовать для связи между двумя процессами на одной машине. В этом случае необходимо указать, что работа производится в области AF_UNIX. Вызовы сокетов для области AF_UNIX те
же, что и для области AF_INET; меняются только структуры, связанные с адресами. Данное
сходство вызо-вов позволяет достаточно легко переходить от локальных задач к сетевым и
обратно.
Использование в режиме с установлением виртуального соединения
Клиент :
- создает сокет;
- подсоединяется к серверу, предоставляя адрес удаленного сокета (адрес Internet сервера и
номер сервисного порта). Это соединение автоматически присваивает клиенту номер порта;
- осуществляет считывание или запись на сокет;
- закрывает сокет.
Сервер:
- создает сокет;
- связывает сокет-адрес (адрес Internet и номер порта) с сервисной программой: "binding";
- переводит себя в состояние "прослушивания" входящих соединений;
- для каждого входящего соединения:
- принимает соединение (создается новый сокет с теми же характеристиками, что и исходный;
- считывает и записывает на новый сокет;
- закрывает новый сокет.
На рис. 4.4. показаны примитивы, используемые для сокетов типа SOCK_STREAM.
Рис. 4.4. Использование сокетов с установлением логического соединения.
Некоторые вызовы способные заблокировать программу : Клиент:
- connect () до того, как сервер осуществит accept ();
- write () при переполнении буфера передачи;
- read () до того, как будет получен хотя бы один символ вследствие операции записи, осуществленной сервером.
Сервер:
- accept () до того, как клиент осуществит connect ();
- read () до того, как будет получен хотя бы один символ, вследствие операции записи, осуществленной клиентом;
- write () при переполнении буфера передачи.
Использование в режиме дейтаграмм
Клиент:
- создает сокет;
- связывает сокет-адрес с сервисной программой: "binding" (операция, являющаяся необходимой только в случае, если процесс должен получить данные);
- считывает или осуществляет запись на сокет.
Сервер:
- создает сокет;
- связывает сокет-адрес с сервисной программой: "binding" (операция необходима только в
случае, если процесс должен получить данные);
- считывает или осуществляет запись на сокет. На рис. 4.5. показаны примитивы, используемые для сокетов типа SOCK_DGRAM.
Адресация
Много вызовов, связанных с сокетами требуют в качестве аргу-мента указатель структуры,
содержащий сокет-адрес, общая структура которого определена в файле <sys/socket.h>:
struct sockaddr {
u_short sa_family; /*AF_UNIX или AF_INET*/
char sa_data [14];/*абсолютный адрес протокола*/
};
Тип u_short, также как и определенное число других используемых типов, определены в
файле <sys/types.h>.
Рис. 4.5. Использование сокетов в режиме дейтаграмм.
Адресация в области AF_INET
В области AF_INET клиент и сервер явно указывают используемый транспортный протокол
(TCP или UDP). Сервер связывает свою сервисную программу с сокет-адресом (адрес Internet
и номер порта), затем переходит в состояние ожидания запросов от кли-ентов. Клиент адресует свои запросы, предоставляя серверу адрес Internet и номер сервисного порта.
В файле <netinet/in.h> определены следующие структуры:
struct in_addr {
u_long s_addr;
};
struct sockaddr_in {
short sin_family; /*AF_INET*/
u_short sin_port; /*номер порта*/
struct in_addr sin_addr; /*машинный адрес Internet*/
char sin_zero [8]; /*не использован*/
};
Краткое описание компонента TServerSocket (Borland)
Здесь мы познакомимся с основными свойствами, методами и событиями компонента
TServerSocket.
Свойства
Методы
События
Socket - класс
TServerWinSocket, через который Вы имеете доступ к
открытым сокетным каналам. Далее мы рассмотрим
это свойство более подробно, т.к. оно, собственно и
есть одно из главных. Тип:
TServerWinSocket;
ServerType - тип сервера.
Может принимать одно из
двух значений:
stNonBlocking - синхронная
работа с клиентскими сокетами. При таком типе сервера Вы можете работать с
клиентами через события
OnClientRead и
OnClientWrite.
stThreadBlocking - асинхронный тип. Для каждого
клиентского сокетного канала создается отдельный
процесс (Thread). Тип:
TServerType;
ThreadCacheSize - количество клиентских процессов
(Thread), которые будут кэшироваться сервером. Здесь
необходимо подбирать
среднее значение в зависимости от загруженности
Вашего сервера. Кэширование происходит для того,
чтобы не создавать каждый
раз отдельный процесс и не
убивать закрытый сокет, а
оставить их для дальнейшего использования. Тип:
Open - Запускает сервер. По
сути, эта команда идентична присвоению значения
True свойству Active;
Close - Останавливает сервер. По сути, эта команда
идентична присвоению значения False свойству Active.
OnClientConnect - возникает, когда клиент установил
сокетное соединение и ждет
ответа сервера (OnAccept);
OnClientDisconnect - возникает, когда клиент отсоединился от сокетного канала;
OnClientError - возникает,
когда текущая операция завершилась неудачно, т.е.
произошла ошибка;
OnClientRead - возникает,
когда клиент передал берверу какие-либо данные.
Доступ к этим данным
можно получить через пеаедаваемый параметр Socket:
TCustomWinSocket;
OnClientWrite - возникает,
когда сервер может отправлять данные клиенту по сокету;
OnGetSocket - в обработчике этого события Вы можете отредактировать параметр ClientSocket;
OnGetThread - в обработчике этого события Вы можете определить уникальный процесс (Thread) для
каждого отдельного клиентского канала, присвоив параметру SocketThread нужную подзадачу
TServerClientThread;
OnThreadStart,
OnThreadEnd - возникает,
когда подзадача (процесс,
Integer;
Active - показатель того,
активен в данных момент
сервер, или нет. Т.е., фактически, значение True указывает на то, что сервер работает и готов к приему
клиентов, а False - сервер
выключен. Чтобы запустить
сервер, нужно просто присвоить этому свойству значение True. Тип: Boolean;
Port - номер порта для
установления соединений с
клиентами. Порт у сервера
и у клиентов должны быть
одинаковыми. Рекомендуются значения от 1025 до
65535, т.к. от 1 до 1024 могут быть заняты системой. Тип: Integer;
Service - строка, определяющая службу (ftp, http,
pop, и т.д.), порт которой
будет использован. Это
своеобразный справочник
соответствия номеров портов различным стандартным
протоколам. Тип: string;
Thread) запускается или
останавливается, соответственно;
OnAccept - возникает, когда сервер принимает клиента или отказывает ему в
соединении;
OnListen - возникает, когда сервер переходит в режим ожидания подсоединения клиентов.
TServerSocket.Socket (TServerWinSocket)
Итак, как же сервер может отсылать данные клиенту? А принимать данные? В основном, если Вы работаете через события OnClientRead и OnClientWrite, то общаться с клиентом можно
через параметр ClientSocket (TCustomWinSocket). Про работу с этим классом можно прочитать в статье про клиентские сокеты, т.к. отправка/посылка данных через этот класс аналогична - методы (Send/Receive)(Text,Buffer,Stream). Также и при работе с
TServerSocket.Socket. Однако, т.к. здесь мы рассматриваем сервер, то следует выделить некоторые полезные свойства и методы:




ActiveConnections (Integer) - количество подключенных клиентов;
ActiveThreads (Integеr) - количество работающих процессов;
Connections (array) - массив, состоящий из отдельных классов TClientWinSocket для
каждого подключенного клиента. Например, такая команда:
ServerSocket1.Socket.Connections[0].SendText('Hello!');
отсылает первому подключенному клиенту сообщение 'Hello!'. Команды для работы с
элементами этого массива - также (Send/Receive)(Text,Buffer, Stream);
IdleThreads (Integer) - количество свободных процессов. Такие процессы кэшируются
сервером (см. ThreadCacheSize);



LocalAddress, LocalHost, LocalPort - соответственно - локальный IP-адрес, хост-имя,
порт;
RemoteAddress, RemoteHost, RemotePort - соответственно - удаленный IP-адрес,
хост-имя, порт;
Методы Lock и UnLock - соответственно, блокировка и разблокировка сокета.
Download