描述
WinHttpWriteData功能将请求数据写入HTTP服务器。
C / C ++语法
BOOL WinHttpWriteData( HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD lpdwNumberOfBytesWritten ); |
PowerBASIC 语法
FUNCTION WinHttpWriteData ( _ BYVAL hRequest AS DWORD, _ BYVAL lpBuffer AS DWORD, _ BYVAL dwNumberOfBytesToWrite AS DWORD, _ BYREF lpdwNumberOfBytesWritten AS DWORD _ ) AS LONG |
参数
hRequest
[in]HINTERNET有效HINTERNET句柄。在致电WinHttpWriteData之前等待WinHttpSendRequest已完成此句柄。
lpBuffer
[in]指向包含要发送到服务器的数据的缓冲区的指针。确保此缓冲区保持有效,直到WinHttpWriteData完成。
dwNumberOfBytesToWrite
[in]包含要写入文件的字节数的无符号长整型值。
lpdwNumberOfBytesToWrite
[out]指向无符号长整数变量的指针,该变量接收写入缓冲区的字节数。在执行任何工作或错误检查之前,WinHttpWriteData函数将此值设置为零。当异步使用WinHTTP时,始终将此参数设置为NULL并检索回调函数中的信息;不这样做可能会导致内存故障。
返回值
如果成功,返回一个有效的会话句柄,否则返回NULL。要检索扩展错误信息,请调用GetLastError.返回的错误代码有:
错误代码 |
描述 |
ERROR_WINHTTP_CONNECTION_ERROR |
与服务器的连接已重置或终止,或遇到不兼容的SSL协议。例如,WinHTTP版本5.1不支持SSL2,除非客户端专门启用它。 |
ERROR_WINHTTP_INCORRECT_HANDLE_STATE |
所请求的操作不能执行,因为提供的手柄不在正确的状态。 |
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE |
提供的手柄类型对于此操作是不正确的。 |
ERROR_WINHTTP_INTERNAL_ERROR |
发生内部错误。 |
ERROR_WINHTTP_OPERATION_CANCELLED |
操作被取消,通常是因为在操作完成之前,请求的操作被关闭。 |
ERROR_WINHTTP_TIMEOUT |
请求已超时。 |
ERROR_NOT_ENOUGH_MEMORY |
没有足够的内存来完成请求的操作。(Windows错误代码) |
备注
即使在异步模式下使用WinHTTP(即,当WinHttpOpen中设置了WINHTTP_FLAG_ASYNC)时,此函数可以同步或异步操作。如果此函数返回FALSE,则此函数失败,您可以调用GetLastError获取扩展错误信息。如果此函数返回TRUE,请使用WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE完成来确定此函数是否成功和参数值。WINHTTP_CALLBACK_STATUS_REQUEST_ERROR完成表示操作异步完成但失败。
警告异步使用WinHTTP时,始终将lpdwNumberOfBytesWritten参数设置为NULL,并检索回调函数中写入的字节;否则可能会发生内存故障。
当应用程序发送数据时,可以调用WinHttpReceiveResponse结束数据传输。如果调用WinHttpCloseHandle,则数据传输将中止。
如果已经使用WinHttpSetStatusCallback安装了状态回调函数,那么在dwNotificationFlags参数WinHttpSetStatusCallback中设置的以下通知的那些指示将数据发送到服务器的进度:
· | WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE |
· | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED |
· | WINHTTP_CALLBACK_STATUS_DATA_WRITTEN |
· | WINHTTP_CALLBACK_STATUS_SENDING_REQUEST |
· | WINHTTP_CALLBACK_STATUS_REQUEST_SENT |
· | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE |
当尝试使用NTLM或协商身份验证对代理或服务器进行POST(或PUT)数据挑战时,可能会出现两个问题。首先,这些代理或服务器可能发送401/407的挑战并关闭所有数据可以被POST之前的连接,在这种情况下,不仅WinHttpWriteData失败,而且WinHTTP也无法应对认证挑战。NTLM和Negotiate要求在相同的套接字连接上交换所有身份验证握手,因此如果连接过早中断,则认证失败。
其次,NTLM和Negotiate可能需要多次握手才能完成身份验证,这需要为这些身份验证“腿”中的每一个重新启动数据。对于大量数据上传,这可能非常低效。
要解决这两个问题,一个解决方案是首先向认证的v-dir发送诸如HEAD的幂等“热身”请求,处理与此请求相关的身份验证挑战,然后处理POST数据。只要相同的套接字被重新用于处理POST,则不应该遇到进一步的认证挑战,并且可以一次上传所有数据。由于认证的套接字只能在同一会话中重新用于后续请求,所以只要套接字并未并入并发请求,POST应该在同一个套接字中。