Последний параметр сокета, который мы рассмотрим, называется SO_LINGER
. Он управляет поведением функции closesocket
. Напомним, что по умолчанию эта функция не блокирует вызвавшую ее нить, а закрывает сокет в фоновом режиме. Параметр SO_LINGER
имеет тип TLinger
, представляющий собой следующую структуру:
TLinger = record
l_onoff: u_short;
l_linger: u_short;
end;
Поле l_onoff
этой структуры показывает, будет ли использоваться фоновый режим закрытия сокета. Нулевое значение показывает, что закрытие выполняется в фоновом режиме, как это установлено по умолчанию (в этом случае поле l_linger
игнорируется). Ненулевое значение показывает, что функция closesocket
не вернет управление вызвавшей ее нити, пока сокет не будет закрыт. В этом случае возможны два варианта: мягкое и грубое закрытие. Мягкое закрытие предусматривает, что перед закрытием сокета все данные, находящиеся в его выходном буфере, будут переданы партнеру. При грубом закрытии данные партнеру не передаются. Поле l_linger
задает время (в секундах), которое дается на передачу данных партнеру. Если за отведенное время данные, находящиеся в выходном буфере сокета, не были отправлены, сокет будет закрыт грубо. Если поле l_linger
будет равно нулю (при ненулевом l_onoff
), сокет всегда будет закрываться грубо. Неблокирующие сокеты рекомендуется закрывать с нулевым временем ожидания или в фоновом режиме, При мягком закрытии неблокирующего сокета не в фоновом режиме, если остались непереданные данные, вызов closesocket
завершится с ошибкой WSAEWOULDBLOCK
, и сокет не будет закрыт. Придется вызывать функцию closesocket
несколько раз до тех пор. пока она не завершится успешно.
Остальные параметры сокета детально описаны в MSDN.
2.1.18. Итоги первого раздела
Мы рассмотрели основные принципы работы со стандартными сокетами. Хотя многое осталось за кадром, того, что здесь было написано, достаточно, чтобы начать создавать разнообразные приложения с использованием сокетов. Для самостоятельного изучения рекомендуется сделать следующее:
□ Для каждой из упоминавшихся здесь функций выяснить, какие ошибки может возвращать WSAGetLastError
в случае неуспешного завершения и что каждая из этих ошибок означает.
□ посмотреть, какие еще параметры (опции) есть у сокета;
□ самостоятельно разобраться с не упомянутыми здесь функциями getsockname
, gethostbyaddr
и getaddrbyhost
.
Из приведенных примеров видно, что стандартные сокеты достаточно интегрируются с пользовательским интерфейсом, однако приложение, использующее их, вынуждено самостоятельно опрашивать сокеты с определённой периодичностью (например, по таймеру). Это не совпадает с принятой в Windows схемой событийного управления программой, основанной на принципе "пусть мне скажут, когда что-то произойдет, и я отреагирую". Именно поэтому стандартные сокеты были расширены и появились сокеты Windows, с которыми мы познакомимся далее.
2.2. Сокеты Windows
В предыдущих разделах мы рассмотрели те методы работы с сокетами, которые восходят еще к сокетам Беркли. Разработчики библиотеки сокетов для Windows добавили в нее также поддержку новых методов, упрощающих работу с сокетами для приложений, имеющих традиционную для Windows событийно-ориентированную модель. В Windows можно использовать асинхронные сокеты и перекрытый ввод-вывод. Далее мы рассмотрим эти расширения, а также ряд новых функций, пришедших на смену "морально устаревшим" функциям из стандартных сокетов.
Материал здесь, как и ранее, не претендует на полноту, а предназначен лишь для знакомства с наиболее часто употребляемыми возможностями библиотеки сокетов. По-прежнему рассматриваются только протоколы TCP и UDP. Не будут затронуты такие вопросы, как поддержка качества обслуживания, пространства имен, простые сокеты (RAW_SOCK
) и SPI (Service Provider Interface); Тем, кто захочет самостоятельно разобраться с данными вопросами, рекомендуем книгу [3].
2.2.1. Версии Windows Sockets
При рассмотрении функции WSAStartup уже упоминалось, что существуют разные версии библиотеки сокетов, которые заметно различаются по функциональности. К сожалению, полный перечень существующих на сегодняшний день версий Windows Sockets и их особенностей в документации в явном виде не приводится, но, изучая разрозненную информацию, можно сделать некоторые выводы, которые приведены в табл. 2.1. В дальнейшем, если не оговорено иное, под WinSock 1 мы будем подразумевать версию 1.1, под WinSock 2 — версию 2.2.