WSASendMsg 函数 (winsock2.h)

WSASendMsg 函数从连接和未连接的套接字发送数据和可选控制信息。

注意 此函数是特定于 Windows 套接字规范的Microsoft扩展。

 

语法

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

存储 Posix.1g msghdr 结构的 WSAMSG 结构。

[in] dwFlags

用于修改 WSASendMsg 函数调用行为的标志。 有关详细信息,请参阅“备注”部分中的“使用 dwFlags

[out] lpNumberOfBytesSent

指向此调用发送的数字(以字节为单位)的指针(如果 I/O 操作立即完成)。

如果 lpOverlapped 参数未 NULL 以避免潜在的错误结果,则对此参数使用 NULL。 仅当 lpOverlapped 参数不 NULL时,此参数才能 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
lpMsglpNumberOfBytesSentlpOverlappedlpCompletionRoutine 参数未完全包含在用户地址空间的有效部分中。 如果 lpMsg 参数指向的 WSAMSG 结构 成员 名称是 NULL 指针,并且 WSAMSG 结构的 namelen 成员未设置为零,则也会返回此错误。 如果由 lpMsg 参数指向的 WSAMSG 结构的 Control.buf 成员是 NULL 指针,并且 Control.lenWSAMSG 结构的成员未设置为零,则也会返回此错误。
WSAEINPROGRESS
正在阻止 Windows 套接字 1.1 调用,或者服务提供商仍在处理回调函数。
WSAEINTR
WSACancelBlockingCall取消了阻止的 Windows 套接字 1.1 调用。
WSAEINVAL
套接字未绑定到 绑定,或者未使用重叠标志创建套接字。
WSAEMSGSIZE
套接字面向消息,并且消息大于基础传输支持的最大大小。
WSAENETDOWN
网络子系统已失败。
WSAENETRESET
对于数据报套接字,此错误指示生存时间已过期。
WSAENETUNREACH
网络无法访问。
WSAENOBUFS
Windows 套接字提供程序报告缓冲区死锁。
WSAENOTCONN
套接字未连接。
WSAENOTSOCK
描述符不是套接字。
WSAEOPNOTSUPP
不支持套接字操作。 如果由 lpMsg 参数指向的 WSAMSG 结构的 dwFlags 成员包含 WSASendMsg无效的任何控制标志,则返回此错误。
WSAESHUTDOWN
套接字已关闭;在调用 关闭 后,无法在套接字上调用 WSASendMsg 函数, 如何设置为SD_SEND或SD_BOTH。
WSAETIMEDOUT
套接字超时。如果使用 SO_SNDTIMEO 套接字选项指定了等待超时,并且超出超时,则会返回此错误。
WSAEWOULDBLOCK
重叠套接字:存在过多未完成的重叠 I/O 请求。 非重叠套接字:套接字被标记为非阻止,无法立即完成发送操作。
WSANOTINITIALIZED
在使用此函数之前,必须成功 WSAStartup 调用。
WSA_IO_PENDING
已成功启动重叠操作,稍后将指示完成操作。
WSA_OPERATION_ABORTED
由于套接字关闭或 WSAIoctl中执行 SIO_FLUSH 命令,已取消重叠操作。

言论

WSASendMsg 函数可用于代替 WSASendWSASendTo 函数。 WSASendMsg 函数只能用于数据报和原始套接字。 必须打开 s 参数中的套接字描述符,并将套接字类型设置为 SOCK_DGRAMSOCK_RAW

dwFlags 参数只能包含以下控件标志的组合:MSG_DONTROUTEMSG_PARTIALMSG_OOBlpMsg 参数指向的 WSAMSG 结构的 dwFlags 成员将被忽略,而不用于输出。

注意 必须使用指定的 SIO_GET_EXTENSION_FUNCTION_POINTER 操作码调用 WSAIoctl 函数,在运行时获取 WSASendMsg 函数的函数指针。 传递给 WSAIoctl 函数的输入缓冲区必须包含 WSAID_WSASENDMSG,这是一个全局唯一标识符(GUID),其值标识 WSASendMsg 扩展函数。 成功后,WSAIoctl 函数返回的输出包含指向 WSASendMsg 函数的指针。 WSAID_WSASENDMSG GUID 在 Mswsock.h 头文件中定义。
 

使用设置了 WSA_FLAG_OVERLAPPED 标志的 WSASocket 函数调用创建重叠套接字。 对于重叠套接字,除非 lpOverlappedlpCompletionRoutineNULL,否则发送信息将使用重叠的 I/O;当 lpOverlappedlpCompletionRoutineNULL时,套接字将被视为非重叠套接字。 完成指示与重叠套接字一起发生;传输使用缓冲区或缓冲区后,将触发完成例程或设置事件对象。 如果操作未立即完成,则通过完成例程或通过调用 WSAGetOverlappedResult 函数来检索最终完成状态。

对于非重叠套接字,lpOverlappedlpCompletionRoutine 参数将被忽略,WSASendMsg 采用与 发送 函数相同的阻塞语义:数据从缓冲区或缓冲区复制到传输的缓冲区中。 如果套接字不阻塞且面向流,并且传输缓冲区中空间不足,则 WSASendMsg 返回,并且只使用应用程序的缓冲区的一部分。 相比之下,阻止套接字上的此缓冲区情况会导致 WSASendMsg 阻塞,直到所有应用程序的缓冲区内容都已使用。

如果此函数以重叠的方式完成,则 Winsock 服务提供商有责任在从此调用返回之前捕获此 WSABUF 结构。 这使应用程序能够生成基于堆栈的 WSABUF 数组,这些数组由 WSAMSG 结构 lpMsg 参数指向的 lpBuffers 成员。

对于面向消息的套接字,必须小心不要超过基础提供程序的最大消息大小,这可以通过获取套接字选项的值 SO_MAX_MSG_SIZE获得。 如果数据太长,无法通过基础协议以原子方式传递,则会返回 WSAEMSGSIZE 错误,并且不会传输任何数据。

在类型 SOCK_DGRAMSOCK_RAW的 IPv4 套接字上,应用程序可以指定用于与 WSASendMsg 函数一起发送的本地 IP 源地址。 WSAMSG 结构中传递给 WSASendMsg 函数的控件数据对象之一可能包含用于指定要用于发送的本地 IPv4 源地址的 in_pktinfo 结构。

在类型 SOCK_DGRAMSOCK_RAW的 IPv6 套接字上,应用程序可以指定用于与 WSASendMsg 函数一起发送的本地 IP 源地址。 WSAMSG 结构中传递给 WSASendMsg 函数的控件数据对象之一可能包含用于指定要用于发送的本地 IPv6 源地址的 in6_pktinfo 结构。

对于使用 WSASendMsg 函数发送数据报时双堆栈套接字,应用程序想要指定要使用的特定本地 IP 源地址,处理此方法取决于目标 IP 地址。 发送到 IPv4 目标地址或 IPv4 映射的 IPv6 目标地址时,WSAMSG 结构中传递的其中一个控制数据对象应包含由 lpMsg 参数指向的 in_pktinfo 结构,该结构包含用于发送的本地 IPv4 源地址。 发送到不是 IPv4 映射 IPv6 地址的 IPv6 目标地址时,WSAMSG 结构中传递的控制数据对象之一应包含 lpMsg 参数指向的 in6_pktinfo 结构,该结构包含用于发送的本地 IPv6 源地址。

注意SO_SNDTIMEO 套接字”选项仅适用于阻止套接字。
 
注意 成功完成 WSASendMsg 并不表示数据已成功传递。
 
注意 发出阻止的 Winsock 调用(如 WSASendMsg),lpOverlapped 参数设置为 NULL 时,Winsock 可能需要等待网络事件才能完成调用。 在这种情况下,Winsock 会执行可警报的等待,这可以通过在同一线程上计划的异步过程调用(APC)中断。 在 APC 中发出另一个阻止 Winsock 调用,中断同一线程上的持续阻止 Winsock 调用将导致未定义的行为,并且永远不会由 Winsock 客户端尝试。
 

dwFlags

dwFlags 输入参数可用于影响函数调用的行为,超出为关联套接字指定的选项。 也就是说,此函数的语义由套接字选项和 dwFlags 参数决定。 后者是使用以下任何值的按位 OR 运算符构造的。
价值 意义
MSG_DONTROUTE 指定数据不应受到路由的约束。 Windows 套接字服务提供程序可以选择忽略此标志。
MSG_PARTIAL 指定 lpMsg->lpBuffers 仅包含部分消息。 请注意,不支持部分消息传输的传输将返回错误代码 WSAEOPNOTSUPP
 

dwFlags 参数的可能值在 winsock2.h 头文件中定义。

在输出中,不使用 lpMsg 参数指向的 WSAMSG 结构的 dwFlags 成员。

重叠套接字 I/O

如果重叠的操作立即完成,WSASendMsg 将返回一个值为零,lpNumberOfBytesSent 参数会更新发送的字节数。 如果重叠操作已成功启动并稍后完成,WSASendMsg 返回SOCKET_ERROR并指示错误代码 WSA_IO_PENDING。 在这种情况下,不会更新 lpNumberOfBytesSent。 重叠操作完成后,通过完成例程中的 cbTransferred 参数或 WSAGetOverlappedResult中的 lcbTransfer 参数来指示传输的数据量。
注意 给定线程启动的所有 I/O 在该线程退出时将被取消。 对于重叠套接字,如果线程在操作完成之前关闭,挂起的异步操作可能会失败。 有关详细信息,请参阅 ExitThread
 

WSARecvWSARecvFrom、、WSARecvFrom的完成例程内调用 WSASendMsg 函数 LPFN_WSARECVMSG(WSARecvMsg)WSASendWSASendMsgWSASendTo 函数。 这允许时间敏感的数据传输完全发生在抢先上下文中。

lpOverlapped 参数在重叠操作期间必须有效。 如果多个 I/O 操作同时未完成,则每个操作都必须引用单独的 WSAOVERLAPPED 结构。

如果 lpCompletionRoutine 参数 NULL,则当重叠操作包含有效事件对象句柄时,lpOverlappedhEvent 参数发出信号。 应用程序可以使用 WSAWaitForMultipleEventsWSAGetOverlappedResult 等待或轮询事件对象。

如果 lpCompletionRoutineNULL,则应用程序将忽略 hEvent 参数,并可供应用程序用来将上下文信息传递给完成例程。 传递非NULLlpCompletionRoutine 的调用方,并且对于同一重叠 I/O 请求,WSAGetOverlappedResult,则不能为调用 WSAGetOverlappedResult 设置 fWait 参数,以 TRUE。 在这种情况下,未定义 hEvent 参数的使用,并且尝试等待 hEvent 参数将产生不可预知的结果。

完成例程遵循与 Windows 文件 I/O 完成例程规定的相同规则。 在线程处于可警报等待状态之前,不会调用完成例程,例如,调用 WSAWaitForMultipleEventsfAlertable 参数设置为 TRUE

传输提供程序允许应用程序从套接字 I/O 完成例程的上下文中调用发送和接收操作,并保证对于给定套接字,I/O 完成例程不会嵌套。 这允许时间敏感的数据传输完全发生在抢先上下文中。

完成例程的原型如下所示。


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.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本中的 Windows 应用商店应用支持此函数。

要求

要求 价值
最低支持的客户端 Windows 8.1、Windows Vista [桌面应用 |UWP 应用]
支持的最低服务器 Windows Server 2008 [桌面应用 |UWP 应用]
目标平台 窗户
标头 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 参考

绑定

in6_pktinfo

in_pktinfo

发送

关闭