• Windows Sockets (Winsock);
• Remote Procedure Call (RPC);
• API доступа к Web;
• именованные каналы (named pipes) и почтовые ящики (mailslots);
• NetBIOS:
• прочие сетевые API.
Windows Sockets
Изначально Windows Sockets (Winsock) версии 1.0 был Microsoft-реализацией BSD (Berkeley Software Distribution) Sockets, программного интерфейса, с 80-х годов прошлого века ставшего стандартом, на основе которого UNIX-системы взаимодействовали через Интернет. Поддержка сокетов в Windows существенно упрощает перенос сетевых приложений из UNIX в Windows. Современные версии Winsock включают большую часть функциональности BSD Sockets, а также содержат специфические расширения от Microsoft, развитие которых продолжается. Winsock поддерживает как надежные коммуникации, ориентированные на логические соединения, так и ненадежные коммуникации, не требующие логических соединений. Windows предоставляет Winsock 2.2 — для устаревших версий Windows он доступен в виде надстройки. Функциональность Winsock 2.2 выходит далеко за рамки спецификации BSD Sockets, и, в частности, он поддерживает функции, использующие средства асинхронного ввода-вывода в Windows, что обеспечивает гораздо более высокую производительность и масштабируемость, чем исходный BSD Sockets.
Winsock обеспечивает:
• ввод-вывод по механизму «scatter/gather» и асинхронный ввод-вывод;
• поддержку Quality of Service (QoS) — если нижележащая сеть поддерживает QoS, приложения могут согласовывать между собой максимальные задержки и полосы пропускания;
• расширяемость — Winsock можно использовать не только с протоколами, которые он поддерживает в Windows, но и с другими;
• поддержку интегрированных пространств имен, отличных от определенных протоколом, который используется приложением вместе с Winsock. Например, сервер может опубликовать свое имя в Active Directory, а клиент, используя расширения пространств имен, — найти адрес сервера в Active Directory;
• поддержку многоадресных сообщений, передаваемых из одного источника сразу нескольким адресатам.
Далее мы рассмотрим принципы работы Winsock и опишем способы его расширения.
Функционирование Winsock на клиентской стороне
Первый шаг Winsock-приложения — инициализация Winsock API вызовом инициализирующей функции. B Windows 2000 такое приложение должно затем создать сокет, представляющий конечную точку коммуникационного соединения. Приложение получает адрес сервера, к которому ему нужно подключиться, вызовом gethostbyname. Winsock не зависит от конкретного протокола, поэтому адрес может быть указан по любому установленному в системе протоколу, поверх которого работает Winsock (TCP/IP, TCP/IP с IP версии 6, IPX). Получив адрес сервера, клиент, ориентированный на логические соединения (connection-oriented client), пытается подключиться к этому серверу, вызывая функцию connect и передавая ей адрес сервера.
B Windows XP и Windows Server 2003 приложение должно получить адрес сервера через getaddrinfo, а не gethostbyname. Функция getaddrinfo возвращает список адресов, назначенных серверу, и клиент пытается поочередно подключиться по каждому из них до тех пор, пока ему не удастся установить соединение. Это гарантирует, что клиент, поддерживающий, например, только IP версии 4 (IPv4), соединится с сервером, которому могли быть назначены как IPv4-, так и IPv6-адpeca, по соответствующему IPv4-адpecy.
Установив соединение, клиент может посылать и принимать данные через свой сокет, используя, например, recv и send. Клиент, не ориентированный на логические соединения (connectionless client), указывает удаленный адрес через эквивалентные функции API, не ориентированного на логические соединения; в данном случае — через sendto и recvfrom соответственно.
Функционирование Winsock на серверной стороне
Последовательность операций серверного приложения отличается от таковой для клиентского. После инициализации Winsock API сервер создает сокет и выполняет его привязку к локальному адресу через bind. Как и в случае клиентского приложения, тип адреса (по TCP/IP, TCP/IP с IP версии 6 или какому-то другому протоколу) выбирается серверным приложением.
Если сервер ориентирован на логические соединения, он выполняет на сокете операцию listen, указывая число соединений, которое он может поддерживать на этом сокете. Далее он выполняет операцию accept, чтобы клиент мог подключиться к сокету. При наличии ждущего запроса на соединение вызов accept завершается немедленно. B ином случае он завершается лишь после поступления запроса на соединение. После того как соединение установлено, функция accept возвращает новый сокет, представляющий серверную сторону соединения. Сервер может выполнять операции приема и передачи данных с помощью таких функций, как, например, recv и send. Рис. 13-3 иллюстрирует коммуникационную связь между клиентом и сервером Winsock, ориентированными на логические соединения.
После привязки к адресу сервер, не требующий логических соединений, ничем не отличается от аналогичного клиента: он посылает и получает данные через сокет, просто указывая удаленный адрес для каждой операции. Большинство протоколов, не ориентированных на логические соединения, ненадежны и, как правило, не позволяют определить, получил ли адресат отправленные ему пакеты данных — дейтаграммы (datagrams). Такие протоколы идеальны для передачи коротких сообщений, когда надежность доставки не играет определяющей роли (впрочем, приложение может само реализовать соответствующие средства поверх протокола).
Расширения Winsock
C точки зрения программирования для Windows, сильной стороной Winsock API является его интеграция с механизмом Windows-сообщений. Winsock-приложение может использовать преимущества такой интеграции для выполнения асинхронных операций с сокетом и приема уведомления о завершении операции через стандартное Windows-сообщение или функцию обратного вызова. Это упрощает разработку Windows-приложений, поскольку позволяет отказаться от многопоточности и синхронизирующих объектов для поддержки сетевого ввода-вывода и реакции на пользовательский ввод или запросы диспетчера окон на обновление окон приложения.
Кроме вспомогательных функций, прямо соответствующих функциям, реализованным в BSD Sockets, Microsoft добавила несколько функций, не входящих в стандарт Winsock. Две из них, AcceptEx и TransmitFile, стоят того, чтобы привести здесь их описание, так как благодаря им многие Web-серверы под управлением Windows достигают высокой производительности. AcceptEx является версией функции accept, которая в процессе установления соединения с клиентом возвращает адрес и первое сообщение клиента. AcceptEx дает возможность серверному приложению подготовиться к серии операций accept для последующей обработки множества входящих соединений. A это позволяет Web-серверу избежать выполнения сразу нескольких Winsock-функций.
Установив соединение с клиентом, Web-сервер обычно посылает ему файл, например Web-страницу. Реализация функции TransmitFile интегрирована с диспетчером кэша, что позволяет серверу посылать файл непосредственно из кэша файловой системы. Такая пересылка данных называется нулевым копированием (zero-сору), поскольку в этом случае серверу не приходится обращаться к файловым данным: он просто указывает описатель файла и диапазон пересылаемых байтов. Кроме того, функция TransmitFile позволяет серверу присоединять к началу или концу файла дополнительные данные. Это дает ему возможность посылать заголовочную информацию, например имя Web-сервера и поле, в котором указывается размер посылаемого сообщения. Internet Information Services (IIS), входящая в комплект поставки Windows, использует как AcceptEx, так и TransmitFile.