Функция WinHttpWriteData (winhttp.h)
Функция WinHttpWriteData записывает данные запроса на HTTP-сервер.
Синтаксис
WINHTTPAPI BOOL WinHttpWriteData(
[in] HINTERNET hRequest,
[in] LPCVOID lpBuffer,
[in] DWORD dwNumberOfBytesToWrite,
[out] LPDWORD lpdwNumberOfBytesWritten
);
Параметры
[in] hRequest
Допустимый дескриптор HINTERNET, возвращаемый WinHttpOpenRequest. Прежде чем вызывать эту функцию, дождитесь завершения WinHttpSendRequest .
[in] lpBuffer
Указатель на буфер, содержащий данные для отправки на сервер. Убедитесь, что этот буфер остается действительным до завершения работы WinHttpWriteData .
[in] dwNumberOfBytesToWrite
Длинное целочисленное значение без знака, содержащее количество байтов для записи в файл.
[out] lpdwNumberOfBytesWritten
Указатель на переменную без знака с длинным целым числом, которая получает число байтов, записанных в буфер. Функция WinHttpWriteData устанавливает для этого значения нулевое значение перед выполнением какой-либо работы или проверки ошибок. При асинхронном использовании WinHTTP этому параметру необходимо задать значение NULL и получить сведения в функции обратного вызова. Это может привести к сбою памяти.
Возвращаемое значение
Возвращает значение TRUE в случае успешного выполнения или FALSE в противном случае. Для получения дополнительных сведений об ошибке вызовите Метод GetLastError. Среди возвращаемых кодов ошибок:
Код ошибки | Описание |
---|---|
|
Соединение с сервером было сброшено или прервано, или обнаружен несовместимый протокол SSL. Например, WinHTTP версии 5.1 не поддерживает SSL2, если только клиент не включает его. |
|
Не удается выполнить запрошенную операцию, так как предоставленный дескриптор находится в неправильном состоянии. |
|
Для этой операции указан неправильный тип дескриптора. |
|
Произошла внутренняя ошибка. |
|
Операция была отменена, как правило, из-за того, что дескриптор, с которым выполнялся запрос, был закрыт до завершения операции. |
|
Истекло время ожидания запроса. |
|
Недостаточно памяти для выполнения запрошенной операции. (Код ошибки Windows) |
Комментарии
Даже если WinHTTP используется в асинхронном режиме (то есть, если WINHTTP_FLAG_ASYNC задано в WinHttpOpen), эта функция может работать синхронно или асинхронно. Если эта функция возвращает значение FALSE, можно вызвать Метод GetLastError , чтобы получить расширенные сведения об ошибке. Если эта функция возвращает значение TRUE, используйте завершение WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, чтобы определить, успешно ли выполнена эта функция и значение параметров. Завершение WINHTTP_CALLBACK_STATUS_REQUEST_ERROR указывает, что операция завершилась асинхронно, но завершилась сбоем.
Если функция обратного вызова состояния была установлена с winHttpSetStatusCallback, то следующие уведомления, заданные в параметре dwNotificationFlagswinHttpSetStatusCallback , указывают на ход отправки данных на сервер:
- 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 и Negotiate может потребоваться несколько подтверждений, что требует повторного получения данных POST для каждого из этапов проверки подлинности. Это может быть очень неэффективно для передачи больших данных.
Чтобы обойти эти две проблемы, одним из решений является отправка идемпотентного запроса на прогревание, например HEAD в проверяющий v-dir, обрабатывать связанные с этим запросом запросы проверки подлинности и только затем данные POST. Если один и тот же сокет повторно используется для обработки post'ing, никаких дополнительных проблем с проверкой подлинности не должно возникать, и все данные можно отправить одновременно. Так как сокет, прошедший проверку подлинности, можно повторно использовать только для последующих запросов в рамках того же сеанса, post должен находиться в том же сокете, если сокет не будет объединен с параллельными запросами, конкурирующими за него.
Примеры
В этом примере показан код, который записывает данные на HTTP-сервер. Имя сервера, указанное в примере , www.wingtiptoys.com, является вымышленным и должно быть заменено именем сервера, для которого у вас есть доступ на запись.
PCSTR pszData = "WinHttpWriteData Example";
DWORD dwBytesWritten = 0;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"PUT",
L"/writetst.txt",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
(DWORD)strlen(pszData), 0);
// Write data to the server.
if (bResults)
bResults = WinHttpWriteData( hRequest, pszData,
(DWORD)strlen(pszData),
&dwBytesWritten);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);
// Report any errors.
if (!bResults)
printf("Error %d has occurred.\n",GetLastError());
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
Требования
Минимальная версия клиента | Windows XP, Windows 2000 Профессиональная с пакетом обновления 3 (SP3) [только классические приложения] |
Минимальная версия сервера | Windows Server 2003, Windows 2000 Server с пакетом обновления 3 (SP3) [только классические приложения] |
Целевая платформа | Windows |
Header | winhttp.h |
Библиотека | Winhttp.lib |
DLL | Winhttp.dll |
Распространяемые компоненты | WinHTTP 5.0 и Internet Обозреватель 5.01 или более поздней версии в Windows XP и Windows 2000. |