Функция WSASendMsg (winsock2.h)

Функция WSASendMsg отправляет данные и дополнительные сведения об управлении из подключенных и неподключенных сокетов.

Примечание Эта функция является расширением майкрософт для спецификации Сокетов Windows.

 

Синтаксис

int WSAAPI WSASendMsg(
  [in]  SOCKET                             Handle,
  [in]  LPWSAMSG                           lpMsg,
  [in]  DWORD                              dwFlags,
  [out] LPDWORD                            lpNumberOfBytesSent,
  [in]  LPWSAOVERLAPPED                    lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Параметры

[in] Handle

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

[in] lpMsg

Структура WSAMSG , в котором хранится структура Posix.1g msghdr .

[in] dwFlags

Флаги, используемые для изменения поведения вызова функции WSASendMsg . Дополнительные сведения см. в разделе Использование dwFlags в разделе Примечания.

[out] lpNumberOfBytesSent

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

Используйте значение NULL для этого параметра, если параметр lpOverlapped не имеет значения NULL , чтобы избежать потенциально ошибочных результатов. Этот параметр может иметь значение NULL , только если параметр lpOverlapped не равен NULL.

[in] lpOverlapped

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

[in] lpCompletionRoutine

Тип: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

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

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

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

Возвращаемое значение SOCKET_ERROR и последующий вызов WSAGetLastError , возвращающий WSA_IO_PENDING, указывает, что перекрывающаяся операция успешно запущена; Затем завершение указывается другими способами, например через события или порты завершения.

При сбое возвращает SOCKET_ERROR , а последующий вызов WSAGetLastError возвращает значение, отличное от WSA_IO_PENDING. В следующей таблице перечислены коды ошибок.

Код ошибки Значение
WSAEACCES
Запрошенный адрес является широковещательным адресом, но соответствующий флаг не установлен.
WSAECONNRESET
Для сокета датаграмм UDP эта ошибка указывает на то, что предыдущая операция отправки привела к сообщению ICMP "Порт недоступен".
WSAEFAULT
Параметр lpMsg, lpNumberOfBytesSent, lpOverlapped или lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя. Эта ошибка также возвращается, если элемент имени структуры WSAMSG , на который указывает параметр lpMsg , был указателем NULL и элемент namelen структуры WSAMSG не был равен нулю. Эта ошибка также возвращается, если элемент Control.buf структуры WSAMSG , на который указывает параметр lpMsg , был указателем NULL , а элемент Control.len структуры WSAMSG не был равен нулю.
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEINTR
Блокирующий вызов сокета Windows 1.1 был отменен через WSACancelBlockingCall.
WSAEINVAL
Сокет не был привязан к привязке или сокет не был создан с перекрывающимся флагом.
WSAEMSGSIZE
Сокет ориентирован на сообщения, и сообщение больше максимального значения, поддерживаемого базовым транспортом.
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAENETRESET
Для сокета датаграмм эта ошибка указывает на то, что срок жизни истек.
WSAENETUNREACH
Сеть недоступна.
WSAENOBUFS
Поставщик сокетов Windows сообщает о взаимоблокировке буфера.
WSAENOTCONN
Сокет не подключен.
WSAENOTSOCK
Дескриптор не является сокетом.
WSAEOPNOTSUPP
Операция сокета не поддерживается. Эта ошибка возвращается, если элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , содержит недопустимые флаги элементов управления для WSASendMsg.
WSAESHUTDOWN
Сокет завершен; Невозможно вызвать функцию WSASendMsg в сокете после вызова завершения работыс параметром SD_SEND или SD_BOTH.
WSAETIMEDOUT
Время ожидания сокета истекло. Эта ошибка возвращается, если для сокета задано время ожидания с помощью параметра сокета SO_SNDTIMEO и превышено время ожидания.
WSAEWOULDBLOCK
Перекрывающиеся сокеты. Существует слишком много невыполненных перекрывающихся запросов ввода-вывода. Неперекрывающиеся сокеты. Сокет помечается как неблокируемый, и операция отправки не может быть завершена немедленно.
WSANOTINITIALISED
Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup .
WSA_IO_PENDING
Перекрываемая операция была успешно инициирована, а завершение будет указано позже.
WSA_OPERATION_ABORTED
Перекрываемая операция была отменена из-за закрытия сокета или выполнения команды SIO_FLUSH в WSAIoctl.

Комментарии

Вместо функций WSASendMsg и WSASendTo можно использовать функцию WSASend. Функцию WSASendMsg можно использовать только с датаграммами и необработанными сокетами. Дескриптор сокета в параметре s должен быть открыт с типом сокета SOCK_DGRAM или SOCK_RAW.

Параметр dwFlags может содержать только сочетание следующих флагов элементов управления: MSG_DONTROUTE, MSG_PARTIAL и MSG_OOB. Элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , игнорируется на входных данных и не используется в выходных данных.

Примечание Указатель функции для функции WSASendMsg должен быть получен во время выполнения путем вызова функции WSAIoctl с указанным SIO_GET_EXTENSION_FUNCTION_POINTER кодом действия. Входной буфер, передаваемый в функцию WSAIoctl , должен содержать WSAID_WSASENDMSG, глобальный уникальный идентификатор (GUID), значение которого определяет функцию расширения WSASendMsg . При успешном выполнении выходные данные, возвращаемые функцией WSAIoctl , содержат указатель на функцию WSASendMsg . Guid WSAID_WSASENDMSG определяется в файле заголовка Mswsock.h .
 

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

Для непереключенных сокетов параметры lpOverlapped и lpCompletionRoutine игнорируются, а WSASendMsg использует ту же семантику блокировки, что и функция отправки : данные копируются из буфера или буферов в буфер транспорта. Если сокет не блокируется и ориентирован на потоки, а в буфере транспорта недостаточно места, функция WSASendMsg возвращает только часть буферов приложения. В отличие от этого, такая ситуация с буфером в блокирующем сокете приводит к блокировке WSASendMsg до тех пор, пока не будет использовано все содержимое буфера приложения.

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

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

В сокете IPv4 типа SOCK_DGRAM или SOCK_RAW приложение может указать локальный IP-адрес источника для отправки с функцией WSASendMsg . Один из объектов управляющих данных, передаваемых в структуре WSAMSG в функцию WSASendMsg , может содержать in_pktinfo структуру, используемую для указания локального адреса источника IPv4, используемого для отправки.

В сокете IPv6 типа SOCK_DGRAM или SOCK_RAW приложение может указать локальный IP-адрес источника для отправки с функцией WSASendMsg . Один из объектов контрольных данных, передаваемых в структуре WSAMSG в функцию WSASendMsg , может содержать in6_pktinfo структуру, используемую для указания локального адреса источника IPv6 для отправки.

Для сокета с двумя стеками при отправке датаграмм с помощью функции WSASendMsg и приложению требуется указать конкретный локальный IP-адрес источника, метод обработки зависит от IP-адреса назначения. При отправке на адрес назначения IPv4 или адрес назначения IPv4, сопоставленный С IPv4, один из объектов управляющих данных, передаваемых в структуре WSAMSG , на которую указывает параметр lpMsg , должен содержать структуру in_pktinfo , содержащую локальный исходный адрес IPv4 для отправки. При отправке на адрес назначения IPv6, который не является IPv4-адресом IPv6, один из объектов управляющих данных, передаваемых в структуре WSAMSG , на которую указывает параметр lpMsg , должен содержать структуру in6_pktinfo , содержащую локальный исходный адрес IPv6, используемый для отправки.

Примечание Параметр сокета SO_SNDTIMEO применяется только к блокирующим сокетам.
 
Примечание Успешное завершение WSASendMsg не означает, что данные были успешно доставлены.
 
Примечание При выполнении блокирующего вызова Winsock, например WSASendMsg , с параметром lpOverlapped , имеющим значение NULL, Winsock может потребоваться дождаться сетевого события перед завершением вызова. В этой ситуации Winsock выполняет оповещенное ожидание, которое может быть прервано асинхронным вызовом процедуры (APC), запланированным в том же потоке. Выполнение другого блокирующего вызова Winsock внутри APC, который прервал текущий блокирующий вызов Winsock в том же потоке, приведет к неопределенному поведению, и клиенты Winsock никогда не должны пытаться его выполнять.
 

Dwflags

Входной параметр dwFlags можно использовать для влияния на поведение вызова функции за пределами параметров, указанных для связанного сокета. То есть семантика этой функции определяется параметрами сокета и параметром dwFlags . Последний создается с помощью побитового оператора OR с любым из следующих значений.
Значение Значение
MSG_DONTROUTE Указывает, что данные не должны подвергаться маршрутизации. Поставщик службы Windows Sockets может игнорировать этот флаг.
MSG_PARTIAL Указывает, что lpMsg-lpBuffers> содержит только частичное сообщение. Обратите внимание, что код ошибки WSAEOPNOTSUPP будет возвращен транспортами, которые не поддерживают частичную передачу сообщений.
 

Возможные значения параметра dwFlags определяются в файле заголовка Winsock2.h .

В выходных данных элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , не используется.

Перекрывающиеся сокеты ввода-вывода

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

Функцию WSASendMsg с использованием перекрывающихся операций ввода-вывода можно вызывать из процедуры завершения предыдущей функции , WSARecv, WSARecvFromLPFN_WSARECVMSG (WSARecvMsg),WSASend, WSASendMsg или WSASendTo . Это позволяет полностью выполнять передачу конфиденциальных во времени данных в контексте вытеснения.

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

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

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

Процедура завершения соответствует тем же правилам, которые предусмотрены для процедур завершения файлового ввода-вывода Windows. Подпрограмма завершения не будет вызываться до тех пор, пока поток не будет находиться в состоянии ожидания с оповещениями, например при вызове WSAWaitForMultipleEvents с параметром fAlertable, равнымTRUE.

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

Ниже приведен прототип процедуры завершения.


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

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

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

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.

Требования

Требование Значение
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2008 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header winsock2.h (включая Mswsock.h)
Библиотека Ws2_32.lib
DLL Ws2_32.dll

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

ExitThread

IPV6_PKTINFO

IP_PKTINFO

WSABUF

WSACancelBlockingCall

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAMSG

WSAOVERLAPPED

WSASend

WSASendTo

WSASocket

WSAStartup

WSAWaitForMultipleEvents

Функции Winsock

Справочник по Winsock

bind

in6_pktinfo

in_pktinfo

send

shutdown