Поделиться через


Функция 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. Среди возвращаемых кодов ошибок:

Код ошибки Описание
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 используется в асинхронном режиме (то есть, если WINHTTP_FLAG_ASYNC задано в WinHttpOpen), эта функция может работать синхронно или асинхронно. Если эта функция возвращает значение FALSE, можно вызвать Метод GetLastError , чтобы получить расширенные сведения об ошибке. Если эта функция возвращает значение TRUE, используйте завершение WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, чтобы определить, успешно ли выполнена эта функция и значение параметров. Завершение WINHTTP_CALLBACK_STATUS_REQUEST_ERROR указывает, что операция завершилась асинхронно, но завершилась сбоем.

Предупреждение При асинхронном использовании WinHTTP всегда присваивайте параметру lpdwNumberOfBytesWrittenзначение NULL и извлекайте байты, записанные в функции обратного вызова; в противном случае может произойти сбой памяти.
 
Когда приложение отправляет данные, оно может вызвать WinHttpReceiveResponse , чтобы завершить передачу данных. Если вызывается WinHttpCloseHandle , передача данных прерывается.

Если функция обратного вызова состояния была установлена с 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
При попытке отправить данные POST (или PUT) на прокси-серверы или серверы, которые оспаривают проверку подлинности NTLM или Negotiate, могут возникнуть две проблемы. Во-первых, эти прокси-серверы или серверы могут отправлять запросы 401/407 и закрывать подключение, прежде чем все данные могут быть отправлены POST. В этом случае winHttpWriteData не только завершается сбоем, но и WinHTTP не может справиться с проблемами проверки подлинности. NTLM и Negotiate требуют, чтобы все подтверждения проверки подлинности обменивались в одном подключении сокета, поэтому проверка подлинности завершается сбоем, если подключение преждевременно разорвано.

Во-вторых, для проверки подлинности NTLM и Negotiate может потребоваться несколько подтверждений, что требует повторного получения данных POST для каждого из этапов проверки подлинности. Это может быть очень неэффективно для передачи больших данных.

Чтобы обойти эти две проблемы, одним из решений является отправка идемпотентного запроса на прогревание, например HEAD в проверяющий v-dir, обрабатывать связанные с этим запросом запросы проверки подлинности и только затем данные POST. Если один и тот же сокет повторно используется для обработки post'ing, никаких дополнительных проблем с проверкой подлинности не должно возникать, и все данные можно отправить одновременно. Так как сокет, прошедший проверку подлинности, можно повторно использовать только для последующих запросов в рамках того же сеанса, post должен находиться в том же сокете, если сокет не будет объединен с параллельными запросами, конкурирующими за него.

Примечание Для Windows XP и Windows 2000 см. раздел Требования к времени выполнения начальной страницы WinHTTP.
 

Примеры

В этом примере показан код, который записывает данные на 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.

См. также раздел

Сведения о службах MICROSOFT Windows HTTP (WinHTTP)

Версии WinHTTP

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest