Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Answers.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
1.55 Mб
Скачать

Программный интерфейс сокетов Сокет

Со́кеты (англ. socket — углубление, гнездо, разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.

Следует различать клиентские и серверные сокеты. Клиентские сокеты грубо можно сравнить с оконечными аппаратами телефонной сети, а серверные — с коммутаторами. Клиентское приложение (например, браузер) использует только клиентские сокеты, а серверное (например, веб-сервер, которому браузер посылает запросы) — как клиентские, так и серверные сокеты.

Интерфейс сокетов впервые появился в BSD Unix. Программный интерфейс сокетов описан в стандарте POSIX.1 и в той или иной мере поддерживается всеми современными операционными системами.

Сокет на сленге системных администраторов означает комбинацию IP-адреса и номера порта, например 10.10.10.10:80.

Каждый процесс может создать слушающий сокет (серверный сокет) и привязать его к какому-нибудь порту операционной системы (тем не менее, в UNIX непривилегированные процессы не могут использовать порты меньше 1024). Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. При этом сохраняется возможность просто проверить наличие соединений на данный момент, установить тайм-аут для операции и так далее.

Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если привязать сокет к UNIX-адресу, то просто будет создан специальный файл (файл сокета) по заданному пути, через который смогут сообщаться любые локальные процессы путём простого чтения/записи из него. Со́кеты типа INET доступны из сети и требуют выделения номера порта.

Обычно клиент явно подсоединяется к слушателю, после чего любое чтение или запись через его файловый дескриптор будут на самом деле передавать данные между ним и сервером.

Сокет (socket) - это конечная точка сетевых коммуникаций. Он является чем-то вроде "портала", через которое можно отправлять байты во внешний мир. Приложение просто пишет данные в сокет; их дальнейшая буферизация, отправка и транспортировка осуществляется используемым стеком протоколов и сетевой аппаратурой. Чтение данных из сокета происходит аналогичным образом.

В программе сокет идентифицируется дескриптором - это просто переменная типа int. Программа получает дескриптор от операционной системы при создании сокета, а затем передаёт его сервисам socket API для указания сокета, над которым необходимо выполнить то или иное действие.

Программный интерфейс сокетов

Вы уже познакомились с интерфейсом сокетов при обсуждении реализации межпроцессного взаимодействия в ОС UNIX. Поскольку сетевая поддержка впервые была разработана именно для BSD UNIX, интерфейс сокетов и сегодня является весьма распространенным при создании сетевых приложений. Сейчас же рассмотрим простой пример приложения клиент-сервер, который демонстрирует возможности сокетов при обеспечении взаимодействия между удаленными процессами. Несмотря на то что взаимодействие затрагивает передачу данных по сети, приведенный пример мало отличается от примера, рассмотренного в разделе "Межпроцессное взаимодействие". Логика приложения сохранена - клиент отправляет серверу сообщение, сервер передает его обратно. Наиболее существенным отличием является коммуникационный домен сокетов, в данном случае AF_INET. Соответственно изменилась и схема адресации коммуникационного узла. Согласно схеме адресации TCP/IP, коммуникационный узел однозначно идентифицируется двумя значениями: адресом хоста (IP-адрес) и адресом процесса (адрес порта). Это отражает и структура sockaddr_in, которая является конкретным видом общей структуры адреса сокета sockaddr. Структура sockaddr_in имеет следующий вид:

struct sockaddr in {

short sin_family; /* Коммуникационный домен AF_INET */

u_short sin_port; /* Номер порта */

struct in_addr sin_addr; /* IP-адрес хоста */

char sin zero[8];

};

Адрес порта должен быть предварительно оговорен между клиентом и сервером.

В заключение заметим, что интерфейс сокетов также поддерживается и в UNIX System V, наряду с другим программным интерфейсом - TLI, который в рамках данного курса рассматриваться не будет.

Приведенный пример в качестве транспортного протокола использует TCP. Это значит, что перед передачей прикладных данных клиент должен установить соединение с сервером. Эта схема, приведенная на рис. 5.10, несколько отличается от рассмотренной в разделе "Межпроцессное взаимодействие. Сокеты", где передача данных осуществлялась без предварительного установления связи и в данном случае соответствовала бы использованию протокола UDP.

Рис. 5.10 Схема установления связи и передачи данных между клиентом и сервером

В соответствии с этой схемой сервер производит связывание с портом, номер которого предполагается известным для клиентов (bind(2)), и сообщает о готовности приема запросов (listen(2)). При получении запроса он с помощью функции accept(2) создает новый сокет, который и обслуживает обмен данными между клиентом и сервером. Для того чтобы сервер мог продолжать обрабатывать поступающие запросы, он порождает отдельный процесс на каждый поступивший запрос. Дочерний процесс, в свою очередь, принимает сообщения от клиента (recv(2)) и передает их обратно (send(2)).

Клиент не выполняет связывания, поскольку ему безразлично, какой адрес будет иметь его коммуникационный узел. Эту операцию выполняет система, выбирая свободный адрес порта и установленный адрес хоста. Далее клиент направляет запрос на установление соединения (connect(2)), указывая адрес сервера (IP-адрес и номер порта). После установления соединения ("тройное рукопожатие") клиент передает сообщение (send(2)), принимает от сервера ответ (recv(2)).

Заметм, что при написании реалных программ часто используется еще ряд функций (gethostbyname(2) - получение IP адреса по имени хоста, htonl, htons, ntohl, ntohs (3) - преобразование порядка следования байтов между принятым в сети и на конкретном хосте, inet_aton, inet_ntoa (3) - преобразование IP-адресов и их составных частей в соответствии с привычной "человеческой" нотацией, например 127.0.0.1).

Необходимо отметить, что на архитектуре IA-32 преобразование порядка следования байтов обязатльно (IA-32 - Least Significant Byte first, в сети Internet - Most Significant Byte first).

Подробное рассмотрение этих и других функций, предназначенных для организации сетевого взаимодействия выходит за рамки данного курса. Для получения дополнительной информации Вы можете обратиться к разделам 2 и 3 справочного руководства (man(1)).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]