Поделиться через


Функция 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 "Port Unreachable".
WSAEFAULT
lpMsg, lpNumberOfBytesSent, lpOverlappedили параметр lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя. Эта ошибка также возвращается, если элемент имени структуры WSAMSG, указываемой параметром lpMsg, был указателем NULL, а элемент namelen элемента структуры WSAMSG не было равно нулю. Эта ошибка также возвращается, если элемент Control.buf элемента структуры WSAMSG, на которую указывает параметр lpMsg, был указателем NULL и элементом Control.len структуры WSAMSG не было равно нулю.
WSAEINPROGRESS
Выполняется блокировка вызова сокетов Windows 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 можно использовать вместо функций WSASend и WSASendTo. Функцию WSASendMsg можно использовать только с диаграммами данных и необработанными сокетами. Дескриптор сокета в параметре должен быть открыт с типом сокета, равным 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 WSAIoctl, содержат указатель на функцию WSASendMsg. Guid WSAID_WSASENDMSG определяется в файле заголовка Mswsock.h.
 

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

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

Если эта функция завершена перекрывающимся способом, перед возвращением из этого вызова поставщик услуг Winsock несет ответственность за запись этой структуры WSABUF. Это позволяет приложениям создавать массивы WSABUF, на которые указывает член структуры 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 или ipPv4-сопоставленный адрес назначения IPv6 один из объектов данных управления, передаваемых в структуре WSAMSG, на которую указывает параметр lpMsg, должен содержать структуру in_pktinfo, содержащую локальный исходный адрес IPv4, используемый для отправки. При отправке в адрес назначения IPv6, который не является ipPv4-сопоставленным 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 может игнорировать этот флаг.
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, WSARecvFrom,LPFN_WSARECVMSG (WSARecvMsg), WSASend, WSASendMsgили функцию WSASendTo. Это позволяет передавать конфиденциальные данные во времени полностью в контексте предварительной защиты.

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

Если параметр lpCompletionRoutineNULL, параметр hEventlpOverlapped сигнализирует, когда операция перекрывается, если она содержит допустимый дескриптор объекта события. Приложение может использовать WSAWaitForMultipleEvents или WSAGetOverlappedResult для ожидания или опроса объекта события.

Если lpCompletionRoutine не NULL, параметр hEvent игнорируется и может использоваться приложением для передачи сведений о контексте в подпрограмму завершения. Вызывающий объект, который передаетlpCompletionRoutine и более поздних вызовов 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]
целевая платформа Виндоус
заголовка winsock2.h (include 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

привязка

in6_pktinfo

in_pktinfo

отправки

завершение работы