Функция WSASendMsg (winsock2.h)
Функция WSASendMsg отправляет данные и дополнительные сведения об управлении из подключенных и неподключенных сокетов.
Синтаксис
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. В следующей таблице перечислены коды ошибок.
Код ошибки | Значение |
---|---|
Запрошенный адрес является широковещательным адресом, но соответствующий флаг не установлен. | |
Для сокета датаграмм UDP эта ошибка указывает на то, что предыдущая операция отправки привела к сообщению ICMP "Порт недоступен". | |
Параметр lpMsg, lpNumberOfBytesSent, lpOverlapped или lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя. Эта ошибка также возвращается, если элемент имени структуры WSAMSG , на который указывает параметр lpMsg , был указателем NULL и элемент namelen структуры WSAMSG не был равен нулю. Эта ошибка также возвращается, если элемент Control.buf структуры WSAMSG , на который указывает параметр lpMsg , был указателем NULL , а элемент Control.len структуры WSAMSG не был равен нулю. | |
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова. | |
Блокирующий вызов сокета Windows 1.1 был отменен через WSACancelBlockingCall. | |
Сокет не был привязан к привязке или сокет не был создан с перекрывающимся флагом. | |
Сокет ориентирован на сообщения, и сообщение больше максимального значения, поддерживаемого базовым транспортом. | |
Произошел сбой сетевой подсистемы. | |
Для сокета датаграмм эта ошибка указывает на то, что срок жизни истек. | |
Сеть недоступна. | |
Поставщик сокетов Windows сообщает о взаимоблокировке буфера. | |
Сокет не подключен. | |
Дескриптор не является сокетом. | |
Операция сокета не поддерживается. Эта ошибка возвращается, если элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , содержит недопустимые флаги элементов управления для WSASendMsg. | |
Сокет завершен; Невозможно вызвать функцию WSASendMsg в сокете после вызова завершения работыс параметром SD_SEND или SD_BOTH. | |
Время ожидания сокета истекло. Эта ошибка возвращается, если для сокета задано время ожидания с помощью параметра сокета SO_SNDTIMEO и превышено время ожидания. | |
Перекрывающиеся сокеты. Существует слишком много невыполненных перекрывающихся запросов ввода-вывода. Неперекрывающиеся сокеты. Сокет помечается как неблокируемый, и операция отправки не может быть завершена немедленно. | |
Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup . | |
Перекрываемая операция была успешно инициирована, а завершение будет указано позже. | |
Перекрываемая операция была отменена из-за закрытия сокета или выполнения команды SIO_FLUSH в WSAIoctl. |
Комментарии
Вместо функций WSASendMsg и WSASendTo можно использовать функцию WSASend. Функцию WSASendMsg можно использовать только с датаграммами и необработанными сокетами. Дескриптор сокета в параметре s должен быть открыт с типом сокета SOCK_DGRAM или SOCK_RAW.
Параметр dwFlags может содержать только сочетание следующих флагов элементов управления: MSG_DONTROUTE, MSG_PARTIAL и MSG_OOB. Элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , игнорируется на входных данных и не используется в выходных данных.
Перекрывающиеся сокеты создаются с помощью вызова функции 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, используемый для отправки.
Dwflags
Входной параметр dwFlags можно использовать для влияния на поведение вызова функции за пределами параметров, указанных для связанного сокета. То есть семантика этой функции определяется параметрами сокета и параметром dwFlags . Последний создается с помощью побитового оператора OR с любым из следующих значений.Значение | Значение |
---|---|
MSG_DONTROUTE | Указывает, что данные не должны подвергаться маршрутизации. Поставщик службы Windows Sockets может игнорировать этот флаг. |
MSG_PARTIAL | Указывает, что lpMsg-lpBuffers> содержит только частичное сообщение. Обратите внимание, что код ошибки WSAEOPNOTSUPP будет возвращен транспортами, которые не поддерживают частичную передачу сообщений. |
В выходных данных элемент dwFlags структуры WSAMSG , на который указывает параметр lpMsg , не используется.
Перекрывающиеся сокеты ввода-вывода
Если перекрывающаяся операция завершается немедленно, WSASendMsg возвращает нулевое значение, а параметр lpNumberOfBytesSent обновляется на количество отправленных байтов. Если перекрывающаяся операция успешно запущена и завершится позже, WSASendMsg возвращает SOCKET_ERROR и указывает код ошибки WSA_IO_PENDING. В этом случае lpNumberOfBytesSent не обновляется. После завершения перекрываемой операции объем передаваемых данных указывается либо с помощью параметра cbTransferred в подпрограмме завершения (если указано), либо с помощью параметра lpcbTransfer в WSAGetOverlappedResult.Функцию 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 |
См. также раздел
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по