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

Функция LPWSPSendTo отправляет данные в определенное место назначения с помощью перекрывающихся операций ввода-вывода.

Синтаксис

LPWSPSENDTO Lpwspsendto;

int Lpwspsendto(
  [in]  SOCKET s,
  [in]  LPWSABUF lpBuffers,
  [in]  DWORD dwBufferCount,
  [out] LPDWORD lpNumberOfBytesSent,
  [in]  DWORD dwFlags,
  [in]  const sockaddr *lpTo,
  [in]  int iTolen,
  [in]  LPWSAOVERLAPPED lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]  LPWSATHREADID lpThreadId,
  [out] LPINT lpErrno
)
{...}

Параметры

[in] s

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

[in] lpBuffers

Указатель на массив структур WSABUF . Каждая структура WSABUF содержит указатель на буфер и длину буфера в байтах. Для приложения Winsock после вызова функции LPWSPSendTo система владеет этими буферами, и приложение может не получить к ним доступ. Буферы данных, на которые ссылается каждая структура WSABUF, принадлежат системе, и приложение может не обращаться к ним в течение всего времени существования вызова.

[in] dwBufferCount

Количество структур WSABUF в массиве lpBuffers .

[out] lpNumberOfBytesSent

Указатель на количество байтов, отправленных этим вызовом.

[in] dwFlags

Набор флагов, указывающий способ, с помощью которого выполняется вызов.

[in] lpTo

Необязательный указатель на адрес целевого сокета в структуре sockaddr .

[in] iTolen

Размер (в байтах) адреса, на который указывает параметр lpTo .

[in] lpOverlapped

Указатель на структуру WSAOverlapped (игнорируется для неперекрывающихся сокетов).

[in] lpCompletionRoutine

Тип: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Указатель на подпрограмму завершения, вызываемую при завершении операции отправки (игнорируется для неперекрывающихся сокетов).

[in] lpThreadId

Указатель на структуру WSATHREADID , которая будет использоваться поставщиком в последующем вызове WPUQueueApc. Поставщик должен хранить указанную структуру WSATHREADID (не указатель на нее), пока не будет возвращена функция WPUQueueApc .

[out] lpErrno

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

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

Если ошибка не возникает и операция получения завершена немедленно, функция LPWSPSendTo возвращает ноль. Обратите внимание, что в этом случае подпрограмма завершения, если она указана, уже будет помещена в очередь. В противном случае возвращается значение SOCKET_ERROR, а в lpErrno доступен определенный код ошибки. Код ошибки WSA_IO_PENDING указывает, что перекрывающаяся операция была успешно инициирована и что завершение будет указано позже. Любой другой код ошибки указывает, что не была инициирована перекрывающаяся операция и не будет никаких указаний завершения.

Код ошибки Значение
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEACCES
Запрошенный адрес является широковещательным адресом, но соответствующий флаг не установлен.
WSAEINTR
(Блокирующий) вызов был отменен через LPWSPCancelBlockingCall.
WSAEINPROGRESS
Выполняется блокировка вызова Windows Sockets или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEFAULT
Параметры lpBuffers или lpTo не являются частью адресного пространства пользователя или параметр lpTo слишком мал.
WSAENETRESET
Подключение было разорвано из-за действия поддержания активности, обнаруживающего сбой во время выполнения операции.
WSAENOBUFS
Поставщик сокетов Windows сообщает о взаимоблокировке буфера.
WSAENOTCONN
Сокет не подключен (только сокеты, ориентированные на подключение).
WSAENOTSOCK
Дескриптор не является сокетом.
WSAEOPNOTSUPP
MSG_OOB указано, но сокет не является потоковым, например тип SOCK_STREAM, данные OOB не поддерживаются в домене связи, связанном с этим сокетом, MSG_PARTIAL не поддерживаются, либо сокет является однонаправленным и поддерживает только операции получения.
WSAESHUTDOWN
Сокет был выключен; невозможно использовать LPWSPSendTo в сокете после вызова LPWSPShutdownс параметром SD_SEND или SD_BOTH.
WSAEWOULDBLOCK
Windows NT: перекрывающиеся сокеты: слишком много невыполненных перекрывающихся запросов ввода-вывода. Неперекрывающиеся сокеты. Сокет помечается как неблокируемый, и операция отправки не может быть завершена немедленно.
WSAEMSGSIZE
Сокет ориентирован на сообщения, и сообщение больше максимального значения, поддерживаемого базовым транспортом.
WSAEINVAL
Сокет не привязан к LPWSPBind или сокет не создан с флагом перекрытия.
WSAECONNABORTED
Виртуальный канал был прерван из-за истечения времени ожидания или другого сбоя.
WSAECONNRESET
Виртуальная цепь была сброшена удаленной стороной.
WSAEADDRNOTAVAIL
Удаленный адрес не является допустимым адресом (например, ADDR_ANY).
WSAEAFNOSUPPORT
Адреса из заданного семейства адресов не могут использоваться с этим сокетом.
WSAEDESTADDRREQ
Требуется адрес назначения.
WSAENETUNREACH
В настоящее время сеть недоступна с этого узла.
WSA_OPERATION_ABORTED
Перекрывающиеся операции были отменены из-за закрытия сокета или выполнения команды SIO_FLUSH в LPWSPIoctl.

Комментарии

Функция LPWSPSendTo обычно используется в сокете без подключения, заданном параметром s , для отправки датаграммы, содержащейся в одном или нескольких буферах, в определенный одноранговый сокет, определенный параметром lpTo . Даже если сокет без подключения ранее был подключен к определенному адресу с помощью функции LPWSPConnect , lpTo переопределяет адрес назначения только для этой датаграммы. В сокете, ориентированном на подключение, параметры lpTo и iToLen игнорируются; в этом случае функция LPWSPSendTo эквивалентна LPWSPSend.

Для перекрывающихся сокетов (созданных с помощью LPWSPSocket с флагом WSA_FLAG_OVERLAPPED) это будет происходить с помощью перекрывающихся операций ввода-вывода, если только lpOverlapped и lpCompletionRoutine не имеют значения NULL , в этом случае сокет считается неперекрытым сокетом. Указание завершения (вызов подпрограммы завершения или настройка объекта события) будет происходить, когда предоставленные буферы были использованы транспортом. Если операция не завершается немедленно, окончательное состояние завершения извлекается с помощью процедуры завершения или LPWSPGetOverlappedResult.

Для неперекрывающихся сокетов параметры lpOverlapped, lpCompletionRoutine и lpThreadId игнорируются, а LPWSPSendTo принимает обычную синхронную семантику. Данные копируются из предоставленных буферов в буфер транспорта. Если сокет не блокируется и ориентирован на поток, а в буфере транспорта недостаточно места, LPWSPSendTo возвращает только часть буферов клиента SPI сокетов Windows. Учитывая ту же ситуацию с буфером и блокирующим сокетом, LPWSPSendTo будет блокироваться до тех пор, пока не будет занято все содержимое буфера клиента SPI сокетов Windows.

Массив структур WSABUF , на которые указывает параметр lpBuffers , является временным. Если эта операция завершается перекрывающимся образом, поставщик услуг обязан захватить эти структуры WSABUF перед возвращением из этого вызова. Это позволяет приложениям создавать массивы WSABUF на основе стека.

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

Обратите внимание, что успешное завершение LPWSPSendTo не означает, что данные были успешно доставлены.

Параметр iFlags можно использовать для влияния на поведение вызова функции за пределами параметров, указанных для связанного сокета. То есть семантика этой функции определяется параметрами сокета и параметром dwFlags . Последний создается с помощью побитового оператора OR с любым из следующих значений.

Значение Значение
MSG_DONTROUTE Указывает, что данные не должны подвергаться маршрутизации. Поставщик службы Windows Sockets может игнорировать этот флаг.
MSG_OOB Отправляет данные OOB (только сокет в стиле потока, например SOCK_STREAM).
MSG_PARTIAL Указывает, что lpBuffers содержит только частичное сообщение. Обратите внимание, что код ошибки WSAEOPNOTSUPP будет возвращен транспортами, которые не поддерживают частичную передачу сообщений.

 

 

Если перекрывающаяся операция завершается немедленно, LPWSPSendTo возвращает нулевое значение, а параметр lpNumberOfBytesSent обновляется числом отправленных байтов. Если перекрывающаяся операция успешно инициирована и завершится позже, LPWSPSendTo возвращает SOCKET_ERROR и указывает код ошибки WSA_IO_PENDING. В этом случае lpNumberOfBytesSent не обновляется. После завершения перекрываемой операции объем передаваемых данных указывается либо с помощью параметра cbTransferred в подпрограмме завершения (если он указан), либо с помощью параметра lpcbTransfer в LPWSPGetOverlappedResult.

Поставщики должны разрешить вызов этой функции из процедуры завершения предыдущей функции LPWSPRecv, LPWSPRecvFrom, LPWSPSend или LPWSPSendTo . Однако для заданного сокета подпрограммы завершения ввода-вывода не могут быть вложенными. Это позволяет полностью выполнять передачу конфиденциальных во времени данных в контексте вытеснения.

Параметр lpOverlapped должен быть действителен в течение всего периода перекрываемой операции. Если одновременно выполняется несколько операций ввода-вывода, каждая из них должна ссылаться на отдельную перекрывающуюся структуру. Структура WSAOverlapped определяется на собственной справочной странице.

Если параметр lpCompletionRoutine имеет значение NULL, поставщик службы сообщает члену hEventобъекта lpOverlapped , когда перекрываемая операция завершается, если она содержит допустимый дескриптор объекта события. Клиенты SPI сокетов Windows могут использовать LPWSPGetOverlappedResult для ожидания или опроса объекта события.

Если значение lpCompletionRoutine не равно NULL, элемент hEvent игнорируется и может использоваться клиентом SPI сокетов Windows для передачи контекстных сведений в подпрограмму завершения. Клиент, который передает lpCompletionRoutine, отличный от NULL, а затем вызывает WSAGetOverlappedResult для того же перекрывающегося запроса ввода-вывода, может не задать для параметра fWait для этого вызова WSAGetOverlappedResult значение TRUE. В этом случае использование элемента hEvent не определено, и попытка ожидания элемента hEvent приведет к непредсказуемым результатам.

Поставщик услуг отвечает за организацию вызова указанной клиентом процедуры завершения после завершения перекрывающейся операции. Так как подпрограмма завершения должна выполняться в контексте того же потока, который инициировал перекрывающуюся операцию, ее нельзя вызвать непосредственно от поставщика услуг. Ws2_32.dll предлагает механизм асинхронного вызова процедур (APC) для упрощения вызова процедур завершения.

Поставщик услуг упорядочивает выполнение функции в правильном потоке путем вызова WPUQueueApc. Эта функция может вызываться из любого контекста процесса и потока, даже из контекста, отличного от потока и процесса, который использовался для инициации перекрываемой операции.

Функция WPUQueueApc принимает в качестве входных параметров указатель на структуру WSATHREADID (предоставленную поставщику через входной параметр lpThreadId ), указатель на вызываемую функцию APC и значение контекста, которое затем передается в функцию APC. Так как доступно только одно значение контекста, сама функция APC не может быть указанной клиентом подпрограммой завершения. Поставщик услуг должен вместо этого предоставить указатель на собственную функцию APC, которая использует предоставленное значение контекста для доступа к необходимым сведениям о результатах для перекрывающейся операции, а затем вызывает подпрограмму завершения, указанную клиентом.

Ниже приведен прототип процедуры завершения, предоставляемой клиентом.

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

CompletionRoutine — это заполнитель для имени функции, предоставленного клиентом. dwError указывает состояние завершения для перекрываемой операции, как указано в lpOverlapped. cbTransferred указывает количество отправленных байтов. В настоящее время значения флагов не определены, и значение dwFlags будет равно нулю. Эта функция не возвращает значение.

Подпрограммы завершения можно вызывать в любом порядке, хотя и не обязательно в том же порядке, в каком выполняются перекрывающиеся операции. Однако поставщик услуг гарантирует клиенту, что отправленные буферы отправляются в том же порядке, в который они предоставляются.

Примечание

Все операции ввода-вывода, инициированные данным потоком, отменяются при выходе из этого потока. Для перекрывающихся сокетов ожидающие асинхронные операции могут завершиться ошибкой, если поток будет закрыт до завершения операций. Дополнительные сведения см. в разделе ExitThread .

Требования

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

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

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket