Функция обратного вызова LPWSPCLOSESOCKET (ws2spi.h)

Функция LPWSPCloseSocket закрывает сокет.

Синтаксис

LPWSPCLOSESOCKET Lpwspclosesocket;

int Lpwspclosesocket(
  [in]  SOCKET s,
  [out] LPINT lpErrno
)
{...}

Параметры

[in] s

Дескриптор, определяющий сокет.

[out] lpErrno

Указатель на код ошибки.

Возвращаемое значение

Если ошибки не произошло, LPWSPCloseSocket возвращает ноль. В противном случае возвращается значение SOCKET_ERROR, а в lpErrno доступен определенный код ошибки.

Код ошибки Значение
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEINPROGRESS
Выполняется блокировка вызова сокетов Windows или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAENOTSOCK
Дескриптор не является сокетом.
WSAEWOULDBLOCK
Сокет помечается как неблокировка, а SO_LINGER устанавливается ненулевое значение времени ожидания.

Комментарии

Эта функция закрывает сокет. Точнее, он освобождает дескриптор сокета s, поэтому дальнейшие ссылки на должны завершиться ошибкой WSAENOTSOCK. Если это последняя ссылка на базовый сокет, связанные сведения об именовании и данные в очереди удаляются. Все блокирующие или асинхронные вызовы, ожидающие в сокете (выданные любым потоком в этом процессе), отменяются без отправки уведомлений. Все ожидающие перекрывающиеся операции, выполняемые любым потоком в этом процессе, также отменяются. Выполняется любое действие завершения, указанное для этих перекрывающихся операций (например, событие, подпрограмма завершения или порт завершения). В этом случае ожидающие перекрывающиеся операции завершаются сбоем с состоянием ошибки WSA_OPERATION_ABORTED . FD_CLOSE не будут публиковаться после вызова LPWSPCloseSocket .

Поведение LPWSPCloseSocket представлено следующим образом:

  • Если SO_DONTLINGER включен (параметр по умолчанию), LPWSPCloseSocket возвращается немедленно, а подключение корректно закрывается в фоновом режиме.

  • Если SO_LINGER включен с нулевым временем ожидания, LPWSPCloseSocket возвращается немедленно, а подключение сбрасывается или прекращается.

    или

  • Если SO_LINGER включен с ненулевым временем ожидания с блокирующим сокетом, LPWSPCloseSocket блокируется до тех пор, пока не будут отправлены все данные или не истечет время ожидания.

  • Если SO_LINGER включен с ненулевым тайм-аутом с неблокировкой сокета, LPWSPCloseSocket возвращается немедленно, что указывает на сбой.

На семантику LPWSPCloseSocket влияют параметры сокета SO_LINGER и SO_DONTLINGER следующим образом.

Параметр Интервал Тип закрытия Ждать закрытия?
SO_DONTLINGER Не волнуйся Нормальная Нет
SO_LINGER Ноль Необратимая Нет
SO_LINGER Ненулевой Нормальная Да

 

 

Если задано SO_LINGER (то есть элемент l_onoff структуры затяжки не имеет нуля), а интервал времени ожидания ( l_linger) равен нулю, LPWSPCloseSocket не блокируется, даже если данные в очереди еще не отправлены или не подтверждены. Это называется жестким или прерванным закрытием, так как виртуальная цепь сокета сбрасывается немедленно, а все неотправленные данные теряются. Любой вызов LPWSPRecv на удаленной стороне канала завершится ошибкой WSAECONNRESET.

Если SO_LINGER задано с ненулевым интервалом времени ожидания для блокирующего сокета, вызов LPWSPCloseSocket блокируется в блокирующем сокете до тех пор, пока не будут отправлены оставшиеся данные или не истечет время ожидания. Это называется корректное отключение. Если истекает время ожидания до отправки всех данных, поставщик услуг должен завершить подключение до возврата LPWSPCloseSocket .

Не рекомендуется включать SO_LINGER с ненулевым интервалом времени ожидания в неблокировке сокета. В этом случае вызов LPWSPCloseSocket завершится ошибкой WSAEWOULDBLOCK , если операция закрытия не может быть завершена немедленно. Если LPWSPCloseSocket завершается сбоем с WSAEWOULDBLOCK, дескриптор сокета по-прежнему действителен и отключение не инициируется.

Клиент Winsock SPI должен снова вызвать LPWSPCloseSocket , чтобы закрыть сокет, хотя LPWSPCloseSocket может продолжать завершаться сбоем, если клиент Winsock SPI не выполняет одно из следующих действий:

  • Отключает SO_DONTLINGER.
  • Включает SO_LINGER с нулевым временем ожидания.
  • Вызывает LPWSPShutdown , чтобы инициировать закрытие.

Если SO_DONTLINGER задано в сокете потока (т. е. элемент l_onoff в структуре затяжки равен нулю), вызов LPWSPCloseSocket возвращается немедленно и не получает WSAEWOULDBLOCK, независимо от того, блокируется ли сокет или не блокируется. Однако все данные, помещенные в очередь для передачи, по возможности будут отправлены до закрытия базового сокета. Это называется корректное отключение и является поведением по умолчанию.

Обратите внимание, что в этом случае поставщик Winsock может хранить любые ресурсы, связанные с сокетом, до тех пор, пока не завершится корректное отключение или поставщик не завершит подключение из-за невозможности завершить операцию в течение определенного поставщиком периода времени. Это может повлиять на клиенты Winsock, которые должны использовать все доступные сокеты. Это поведение по умолчанию; SO_DONTLINGER задано по умолчанию.

Требования

Требование Значение
Минимальная версия клиента Windows 2000 Professional [только классические приложения]
Минимальная версия сервера Windows 2000 Server [только классические приложения]
Верхняя часть ws2spi.h

См. также раздел

LPWSPAccept

LPWSPIoctl

WSPSetSockOpt

LPWSPSocket