LPWSPSENDTO 回调函数 (ws2spi.h)
LPWSPSendTo 函数使用重叠 I/O 将数据发送到特定目标。
语法
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
lpBuffers 数组中的 WSABUF 结构数。
[out] lpNumberOfBytesSent
指向此调用发送的字节数的指针。
[in] dwFlags
一组指定调用方式的标志。
[in] lpTo
指向 sockaddr 结构中目标套接字地址的可选指针。
[in] iTolen
lpTo 参数指向的地址的大小(以字节为单位)。
[in] lpOverlapped
对于) , (忽略指向 WSAOverlapped 结构的指针。
[in] lpCompletionRoutine
类型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
指向完成发送操作时调用的完成例程的指针, (忽略非重叠套接字) 。
[in] lpThreadId
指向 WSATHREADID 结构的指针,供提供程序在后续调用 WPUQueueApc 时使用。 在 WPUQueueApc 函数返回之前,提供程序应存储引用的 WSATHREADID 结构 (而不是指向同一) 的指针。
[out] lpErrno
指向错误代码的指针。
返回值
如果未发生错误,并且接收操作已立即完成, 则 LPWSPSendTo 返回零。 请注意,在这种情况下,完成例程(如果指定)已排队。 否则,将返回值 SOCKET_ERROR,并且 lpErrno 中提供了特定的错误代码。 错误代码 WSA_IO_PENDING 指示重叠操作已成功启动,稍后将指示完成。 任何其他错误代码指示未启动重叠操作,也不会发生完成指示。
错误代码 | 含义 |
---|---|
网络子系统发生故障。 | |
请求的地址是广播地址,但未设置相应的标志。 | |
(阻止) 调用已通过 LPWSPCancelBlockingCall 取消。 | |
正在阻止 Windows 套接字调用,或者服务提供商仍在处理回调函数。 | |
lpBuffers 或 lpTo 参数不是用户地址空间的一部分,或者 lpTo 参数太小。 | |
由于操作执行过程中持续的活动检测到故障,连接损坏。 | |
Windows 套接字提供程序报告缓冲区死锁。 | |
仅) (面向连接的套接字未连接。 | |
:描述符不是套接字。 | |
已指定MSG_OOB,但套接字不是流样式(如类型SOCK_STREAM),与此套接字关联的通信域中不支持 OOB 数据,MSG_PARTIAL不受支持,或者套接字是单向的,仅支持接收操作。 | |
套接字已关闭;在调用 LPWSPShutdown并将其设置为SD_SEND或SD_BOTH后,无法在套接字上使用 LPWSPSendTo。 | |
Windows NT:重叠套接字:存在过多未完成的重叠 I/O 请求。未重叠的套接字:套接字标记为非阻止,并且无法立即完成发送操作。 | |
套接字面向消息,消息大于基础传输支持的最大值。 | |
套接字尚未使用 LPWSPBind 绑定,或者未使用重叠标志创建套接字。 | |
虚拟线路因超时或其他故障而终止。 | |
远程端重置了虚拟线路。 | |
远程地址不是 (的有效地址,例如,ADDR_ANY) 。 | |
指定系列中的地址无法与此套接字一起使用。 | |
目标地址是必需的。 | |
此时不可以从此主机访问该网络。 | |
由于套接字关闭或 LPWSPIoctl 中SIO_FLUSH命令的执行,重叠操作已取消。 |
注解
LPWSPSendTo 函数通常用于由 指定的无连接套接字,以将一个或多个缓冲区中包含的数据报发送到由 lpTo 参数标识的特定对等套接字。 即使以前使用 LPWSPConnect 函数将无连接套接字连接到特定地址, lpTo 也仅覆盖该特定数据报的目标地址。 在面向连接的套接字上, lpTo 和 iToLen 参数将被忽略;在本例中, LPWSPSendTo 函数等效于 LPWSPSend。
对于 (使用带有标志的 LPWSPSocket 创建的重叠套接字WSA_FLAG_OVERLAPPED) 将使用重叠 I/O 进行此操作,除非 lpOverlapped 和 lpCompletionRoutine 都是 NULL ,在这种情况下,套接字被视为未重叠的套接字。 当传输已使用提供的缓冲区 (s) ) 时, (调用完成例程或事件对象的设置时,就会发生完成指示。 如果操作未立即完成,则通过完成例程或 LPWSPGetOverlappedResult 检索最终完成状态。
对于非重叠套接字,将忽略参数 lpOverlapped、 lpCompletionRoutine 和 lpThreadId , LPWSPSendTo 采用常规同步语义。 数据从提供的缓冲区 () 复制到传输的缓冲区。 如果套接字是非阻塞且面向流的,并且传输缓冲区中没有足够的空间, 则 LPWSPSendTo 将仅返回部分已使用的 Windows 套接字 SPI 客户端缓冲区。 鉴于相同的缓冲区情况和阻塞套接字, LPWSPSendTo 将阻止,直到使用所有 Windows 套接字 SPI 客户端的缓冲区内容。
lpBuffers 参数指向的 WSABUF 结构的数组是暂时性的。 如果此操作以重叠方式完成,则服务提供商负责在从此调用返回之前捕获这些 WSABUF 结构。 这使应用程序能够生成基于堆栈的 WSABUF 数组。
对于面向消息的套接字,必须注意不要超过基础传输的最大消息大小,这可以通过获取套接字选项的值SO_MAX_MSG_SIZE获得。 如果数据太长,无法通过基础协议以原子方式传递,则返回错误 WSAEMSGSIZE ,并且不会传输任何数据。
请注意, 成功完成 LPWSPSendTo 并不表示数据已成功传递。
iFlags 参数可用于影响函数调用的行为,超出为关联套接字指定的选项。 也就是说,此函数的语义由套接字选项和 dwFlags 参数确定。 后者是使用以下任何值的按位 OR 运算符构造的。
Value | 含义 |
---|---|
MSG_DONTROUTE | :指定数据不应受到路由的约束。 Windows 套接字服务提供商可以选择忽略此标志。 |
MSG_OOB | 仅) SOCK_STREAM等流式套接字 (发送 OOB 数据。 |
MSG_PARTIAL | 指定 lpBuffers 仅包含部分消息。 请注意,不支持部分消息传输的传输将返回错误代码 WSAEOPNOTSUPP 。 |
如果重叠操作立即完成, LPWSPSendTo 将返回一个零值,并使用发送的字节数更新 lpNumberOfBytesSent 参数。 如果重叠操作已成功启动并将稍后完成, 则 LPWSPSendTo 将返回SOCKET_ERROR并指示错误代码WSA_IO_PENDING。 在这种情况下,不会更新 lpNumberOfBytesSent 。 当重叠操作完成时,通过完成例程中的 cbTransferred 参数(如果指定 () )或通过 LPWSPGetOverlappedResult 中的 lcbTransfer 参数指示传输的数据量。
提供程序必须允许从以前的 LPWSPRecv、LPWSPRecvFrom、LPWSPSend 或 LPWSPSendTo 函数的完成例程中调用此函数。 但是,对于给定的套接字,I/O 完成例程不能嵌套。 这允许时间敏感型数据传输完全在先发制人的上下文中进行。
lpOverlapped 参数必须在重叠操作期间有效。 如果多个 I/O 操作同时未完成,则每个操作都必须引用单独的重叠结构。 WSAOverlapped 结构在其自己的引用页中定义。
如果 lpCompletionRoutine 参数为 null,则当重叠操作完成时,如果它包含有效的事件对象句柄,则服务提供商会向 lpOverlapped 的 hEvent 成员发出信号。 Windows 套接字 SPI 客户端可以使用 LPWSPGetOverlappedResult 等待或轮询事件对象。
如果 lpCompletionRoutine 不 为 null,则 忽略 hEvent 成员,并且 Windows 套接字 SPI 客户端可以使用该成员将上下文信息传递给完成例程。 为同一重叠 I/O 请求传递非 nulllpCompletionRoutine 并稍后调用 WSAGetOverlappedResult 的客户端可能不会将 WSAGetOverlappedResult 调用的 fWait 参数设置为 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 值为零。 此函数不返回值。
可以按任意顺序调用完成例程,但不一定按照重叠操作完成的顺序调用。 但是,服务提供商向客户端保证发布的缓冲区的发送顺序与提供的缓冲区相同。
注意
当给定线程退出时,将取消由该线程发起的所有 I/O。 对于重叠的套接字,如果在操作完成之前关闭线程,挂起的异步操作可能会失败。 有关详细信息 ,请参阅 ExitThread 。
要求
最低受支持的客户端 | Windows 2000 Professional [仅限桌面应用] |
最低受支持的服务器 | Windows 2000 Server [仅限桌面应用] |
标头 | ws2spi.h |