LPWSPSEND 回调函数 (ws2spi.h)

LPWSPSend 函数在连接的套接字上发送数据。

语法

LPWSPSEND Lpwspsend;

int Lpwspsend(
  [in]  SOCKET s,
  [in]  LPWSABUF lpBuffers,
  [in]  DWORD dwBufferCount,
  [out] LPDWORD lpNumberOfBytesSent,
  [in]  DWORD dwFlags,
  [in]  LPWSAOVERLAPPED lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]  LPWSATHREADID lpThreadId,
  [out] LPINT lpErrno
)
{...}

参数

[in] s

标识已连接套接字的描述符。

[in] lpBuffers

指向 WSABUF 结构数组的指针。 每个 WSABUF 结构都包含指向缓冲区的指针和缓冲区的长度(以字节为单位)。 对于 Winsock 应用程序,调用 LPWSPSend 函数后,系统将拥有这些缓冲区,应用程序可能无法访问它们。 每个 WSABUF 结构中引用的数据缓冲区归系统所有,应用程序在调用的生存期内可能无法访问它们。

[in] dwBufferCount

lpBuffers 数组中的 WSABUF 结构数。

[out] lpNumberOfBytesSent

指向此调用发送的字节数的指针。

[in] dwFlags

一组标志,指定调用方式。

[in] lpOverlapped

指向 WSAOverlapped 结构的指针 (忽略非重叠套接字) 。

[in] lpCompletionRoutine

类型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

指向完成发送操作时调用的完成例程的指针, (忽略未重叠的套接字) 。

[in] lpThreadId

指向 WSATHREADID 结构的指针,供提供程序在后续调用 WPUQueueApc 时使用。 在 WPUQueueApc 函数返回之前,提供程序应存储引用的 WSATHREADID 结构 (而不是指向同一) 的指针。

[out] lpErrno

指向错误代码的指针。

返回值

如果未发生任何错误,并且发送操作已立即完成, 则 LPWSPSend 返回零。 请注意,在这种情况下,完成例程(如果指定)已排队。 否则,返回值 SOCKET_ERROR,并在 lpErrno 中提供特定的错误代码。 错误代码 WSA_IO_PENDING 指示重叠操作已成功启动,稍后将指示完成。 任何其他错误代码指示未启动重叠的操作,并且不会发生完成指示。

错误代码 含义
WSAENETDOWN
网络子系统失败。
WSAEACCES
请求的地址是广播地址,但未设置相应的标志。
WSAEINPROGRESS
正在阻止 Windows 套接字调用,或者服务提供程序仍在处理回调函数。
WSAEFAULT
lpBuffers 参数并不完全包含在用户地址空间的有效部分。
WSAENETRESET
由于远程主机重置,连接已中断。
WSAENOBUFS
由于操作执行过程中持续的活动检测到故障,连接损坏。
WSAENOTCONN
套接字未连接。
WSAENOTSOCK
:描述符不是套接字。
WSAEOPNOTSUPP
MSG_OOB已指定,但套接字不是流样式(如类型SOCK_STREAM),与此套接字关联的通信域中不支持 OOB 数据,MSG_PARTIAL不受支持,或者套接字是单向的,仅支持接收操作。
WSAESHUTDOWN
套接字已关闭;在调用 LPWSPShutdown 后,无法在套接字上发送 LPWSPSend ,如何将 设置为 SD_SEND 或 SD_BOTH。
WSAEWOULDBLOCK
**Windows NT:** 重叠套接字:存在过多未完成的重叠 I/O 请求。未重叠的套接字:套接字标记为非阻止,并且无法立即完成发送操作。
WSAEMSGSIZE
套接字面向消息,并且消息大于基础传输支持的最大大小。
WSAEINVAL
套接字未与 LPWSPBind 绑定,或者未使用重叠标志创建套接字。
WSAECONNABORTED
虚拟线路因超时或其他故障而终止。
WSAECONNRESET
远程端重置了虚拟线路。
WSA_OPERATION_ABORTED
由于套接字关闭或在 LPWSPIoctl 中执行 SIO_FLUSH 命令,重叠操作已取消。

注解

LPWSPSend 函数用于从 指定的面向连接的套接字上的一个或多个缓冲区写入传出数据。 但是,它也可用于具有通过 LPWSPConnect 函数建立的指定默认对等地址的无连接套接字。

对于 (使用带有标志的 LPWSPSocket 创建的重叠套接字WSA_FLAG_OVERLAPPED) 将使用重叠 I/O 进行创建,除非 lpOverlappedlpCompletionRoutine 均为 null,在这种情况下,套接字被视为未重叠的套接字。 当传输已使用提供的缓冲区 (s) 时, (调用完成例程或事件) 对象的设置时,就会发生完成指示。 如果操作未立即完成,则通过完成例程或 LPWSPGetOverlappedResult 检索最终完成状态。

对于非重叠套接字,将忽略参数 lpOverlappedlpCompletionRoutinelpThreadIdLPWSPSend 采用常规同步语义。 数据从提供的缓冲区 () 复制到传输的缓冲区中。 如果套接字是非阻塞且面向流的,并且传输的缓冲区中没有足够的空间, 则 LPWSPSend 将返回,只使用部分提供的缓冲区。 给定相同的缓冲区情况和阻塞套接字, LPWSPSend 将阻止,直到使用所有提供的缓冲区内容。

lpBuffers 参数指向的 WSABUF 结构数组是暂时性的。 如果此操作以重叠的方式完成,则服务提供商负责在从此调用返回之前捕获这些 WSABUF 结构。 这使应用程序能够生成基于堆栈的 WSABUF 数组。

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

请注意, 成功完成 LPWSPSend 并不表示数据已成功传递。

dwFlags 可用于影响为关联套接字指定的选项之外的函数调用行为。 也就是说,此函数的语义由套接字选项和 dwFlags 参数确定。 后者是使用以下任一值的按位 OR 运算符构造的。

含义
MSG_DONTROUTE :指定数据不应受到路由的约束。 Windows 套接字服务提供程序可以选择忽略此标志。
MSG_OOB 仅) (流式套接字(例如SOCK_STREAM)发送 OOB 数据。
MSG_PARTIAL 指定 lpBuffers 仅包含部分消息。 请注意,对于不支持部分消息传输的消息,将返回错误代码 WSAEOPNOTSUPP

 

 

如果重叠操作立即完成, LPWSPSend 将返回零值,并使用发送的字节数更新 lpNumberOfBytesSent 参数。 如果已成功启动重叠操作并将稍后完成, 则 LPWSPSend 将返回SOCKET_ERROR并指示 错误代码WSA_IO_PENDING。 在这种情况下,不会更新 lpNumberOfBytesSent 。 当重叠操作完成时,通过完成例程中的 cbTransferred 参数(如果指定 () )或通过 LPWSPGetOverlappedResult 中的 lcbTransfer 参数指示传输的数据量。

提供程序必须允许从以前的 LPWSPRecv、LPWSPRecvFromLPWSPSendLPWSPSendTo 函数的完成例程中调用此函数。 但是,对于给定的套接字,I/O 完成例程不能嵌套。 这允许时间敏感型数据传输完全在先发制人的上下文中进行。

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

如果 lpCompletionRoutine 参数为 null,则当重叠操作完成时,如果包含有效的事件对象句柄,则服务提供程序会向 lpOverlappedhEvent 成员发出信号。 Windows 套接字 SPI 客户端可以使用 LPWSPGetOverlappedResult 等待或轮询事件对象。

如果 lpCompletionRoutine 不为 null,则 忽略 hEvent 成员,Windows 套接字 SPI 客户端可以使用该成员将上下文信息传递给完成例程。 为相同的重叠 I/O 请求传递非 null lpCompletionRoutine 并稍后调用 WSAGetOverlappedResult 的客户端可能不会将 WSAGetOverlappedResult 调用的 fWait 参数设置为 TRUE。 在这种情况下, hEvent 成员的用法未定义,并且尝试等待 hEvent 成员将产生不可预知的结果。

服务提供商通过调用 WPUQueueApc 安排在适当的线程和进程上下文中执行的函数。 可以从任何进程和线程上下文调用此函数,甚至是不同于用于启动重叠操作的线程和进程的上下文。

服务提供商通过调用 WPUQueueApc 安排在适当的线程中执行的函数。 请注意,在同一进程的上下文中,必须调用此函数 (但不一定是用于启动重叠操作的同一线程) 。 服务提供商负责在调用 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

另请参阅

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket