Глава 21
Программный интерфейс socket
21.1 Введение
Коммуникационные стандарты определяют все правила для обмена информацией в сети. Однако до некоторого момента игнорировалась необходимость стандартизации интерфейса программирования приложений (Application Programming Interface — API). Как же тогда программист должен создавать приложения клиент/сервер, если программы на каждом из компьютеров совершенно различны?
21.1.1 Программный интерфейс Berkeley
К счастью, большинство реализаций TCP/IP обеспечивает программный интерфейс, следующий очень простой модели
Программный интерфейс socket разрабатывался для применения с различными коммуникационными протоколами, а не только для TCP/IP. Однако, когда была закончена спецификация транспортного уровня OSI, стало ясно, что этот интерфейс не согласуется с требованиями OSI.
В 1986 г. компания AT&T предложила спецификацию протокола интерфейса транспортного уровня (Transport Layer Interface — TLI) для операционной системы Unix System V. Интерфейс TLI мог применяться для транспортного уровня OSI, TCP и других протоколов.
Еще одним важным событием в истории socket стал программный интерфейс socket для Windows (WinSock), позволивший приложениям Windows функционировать поверх стеков TCP/IP, созданных разными производителями. В Windows 95 обеспечивается поддержка многопротокольного интерфейса.
Интерфейс socket стал стандартом де-факто благодаря широкому распространению и универсальности доступа. В этой главе мы рассмотрим общие принципы работы этого интерфейса. На компьютерах могут существовать незначительные отличия в API, связанные с тем, что коммуникационные службы в операционных системах реализуются по-разному. Детальную информацию по программированию в конкретной системе можно найти в технических описаниях.
21.1.2 Ориентация на Unix
Исходный вариант интерфейса socket был разработан для Unix. Архитектура этой операционной системы позволяет единообразно обращаться к файлам, терминалам и вводу/выводу. Операции с файлами предполагают использование одного из следующих вызовов:
descriptor = open(filename, readwritemode)
read(descriptor, buffer, length)
write(descriptor, buffer, length)
close(descriptor)
Когда программа открывает файл, вызов создает в памяти область, называемую
Вызов возвращает небольшое целое число, именуемое
Похожие методы используются в socket для TCP/IP. Главным отличием между программным интерфейсом socket и файловой системой Unix является то, что в socket применяется несколько дополнительных предварительных вызовов, необходимых для сбора всех сведений перед формированием соединения. Не считая дополнительной работы при запуске, для чтения или записи, в сети применяются те же самые операции.
21.2 Службы socket
Программный интерфейс socket обеспечивает работу трех служб TCP/IP:
Рис. 21.1. Программный интерфейс socket
Вспомним, что API интерфейса socket разрабатывался не только для TCP/IP. Исходная цель заключалась в создании единого интерфейса для различных коммуникационных протоколов, в том числе и для XNS (Xerox Network Systems).
Результат получился несколько странным. Например, некоторые вызовы socket содержат необязательные параметры, не имеющие никакого отношения к TCP/IP — они необходимы в других протоколах. Кроме того, иногда программист обязан указывать длину для параметров фиксированного размера, например для адресов IP версии 4. Смысл этого в том, что, хотя длина адреса в IP версии 4 всегда равна 4 байт, в программных интерфейсах для других протоколов могут использоваться адреса другой длины.
21.3 Блокированные и неблокированные вызовы
Когда программа читает данные из сетевого соединения, трудно предсказать заранее, как долго будет продолжаться эта операция. Программист может только дождаться полного завершения чтения или перейти на другое место в программе и периодически проверять значение переменной статуса соединения, либо разрешить программное прерывание по окончании операции.
■ Вызов с последующим ожиданием называется блокированным (blocking) или синхронным (synchronous).
■ Вызов с переходом на выполнение других операций называется неблокированным (nonblocking) или асинхронным (asynchronous).
В программном интерфейсе socket вызовы могут быть блокированными или неблокированными, а программист способен управлять поведением вызова.