Ранее мы уже говорили, что в системах с несколькими сетевыми картами привязка сокета к адресу в том случае, когда его выбор доверен системе, может осуществляться не во время выполнения функции bind
INADDR_ANY
, допускают подключение к ним по любому сетевому интерфейсу, который имеется в системе. Сокет, который создается таким сервером при подключении клиента, будет автоматически привязан к IP-адресу того сетевого интерфейса, через который осуществляется взаимодействие с подключившимся клиентом. Таким образом, сокеты, созданные для взаимодействия с разными клиентами, могут оказаться привязанными к разным адресам.После успешного завершения функций socket
bind
сокет создан и готов к работе. Дальнейшие действия с ним зависят от того, какой протокол он реализует и для какой роли предназначен. Мы разберем эти операции в разделах, посвященных соответствующим протоколам. Там же мы увидим, что в некоторых случаях можно обойтись без вызова функции bind
, поскольку она будет неявно вызвана при вызове других функций библиотеки сокетов.Когда сокет больше не нужен, следует освободить связанные с ним ресурсы. Это выполняется в два этапа: сначала сокет "выключается", а потом закрывается.
Для выключения сокета предусмотрена функция shutdown
function shutdown(s: TSocket; how: Integer): Integer;
Параметр s
how
может принимать значения SD_RECEIVE
, SD_SEND
или SD_BOTH
. Функция возвращает ноль при успешном выполнении и SOCKET_ERROR
— в случае ошибки. Вызов функции с параметром SD_RECEIVE
запрещает чтение данных из входного буфера сокета. Однако на у ровне протокола вызов этой функции игнорируется: дейтаграммы UDP и пакеты TCP, посланные данному сокету, продолжают помещаться в буфер, хотя программа уже не может их оттуда забрать.При указании значения SD_SEND
shutdown
в буфере для исходящих остаются данные, сначала посылаются они. а потом только сигнал о завершении. Поскольку протокол UDP подобных сигналов не предусматривает, то в этом случае shutdown
просто запрещает библиотеке сокетов использовать указанный сокет для отправки данных.Параметр SD_BOTH
Модуль WinSock
SD_XXX
. Чтобы использовать их в своей программе, нужно объявить их так, как показано в листинге 2.5.const
SD_RECEIVE = 0;
SD_SEND = 1;
SD_BOTH = 2;
Для освобождения ресурсов, связанных с сокетом, служит функция closesocket
SOCKET_ERROR
. После вызова этой функции соответствующий дескриптор сокета перестает иметь смысл, и использовать его больше нельзя.