【问题标题】:WinHttpReadData in Win32 app dont work properlyWin32 应用程序中的 WinHttpReadData 无法正常工作
【发布时间】:2013-11-11 13:26:35
【问题描述】:

我使用 WinHTTP 从 URL http://www.google.com/complete/search?output=toolbar&hl=vi&q=hoazzztf 获取文本。回复文本必须是:<toplevel/> 但我得到这样的回复:

                   

有什么想法吗?谢谢!
(回复文本可能包含 UTF-8 字符)

DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BOOL bResults = FALSE;

  hSession = WinHttpOpen(L"WinHTTP Example/1.0",
      WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
      WINHTTP_NO_PROXY_NAME,
      WINHTTP_NO_PROXY_BYPASS, 0);

  WinHttpSetTimeouts(hSession, 1000, 2000, 1000, 1000);

  // Specify an HTTP server.
  if (hSession)
      hConnect = WinHttpConnect(hSession, L"www.google.com",
      INTERNET_DEFAULT_HTTPS_PORT, 0);

  // Create an HTTP request handle.
  if (hConnect)
      hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/complete/search?output=toolbar&hl=vi&q=hoazzztf",
      NULL, WINHTTP_NO_REFERER,
      WINHTTP_DEFAULT_ACCEPT_TYPES,
      WINHTTP_FLAG_SECURE);

  // Send a request.
  if (hRequest)
      bResults = WinHttpSendRequest(hRequest,
      WINHTTP_NO_ADDITIONAL_HEADERS,
      0, WINHTTP_NO_REQUEST_DATA, 0,
      0, 0);

  if (bResults)
      bResults = WinHttpReceiveResponse(hRequest, NULL);

  if (!bResults)
  {
      SetWindowText(hWnd, L"ERR-4");
      break;
  }

  if (bResults)
  {
      do
      {
          // Check for available data.
          dwSize = 0;
          if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
          {
              break;
          }

          // No more available data.
          if (!dwSize)
              break;

          // Allocate space for the buffer.
          pszOutBuffer = new char[dwSize + 1];
          if (!pszOutBuffer)
          {
              break;
          }

          // Read the Data.
          ZeroMemory((LPVOID)pszOutBuffer, dwSize + 1);

          if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
              dwSize, &dwDownloaded))
          {
          }
          else
          {
              MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);
          }

          // Free the memory allocated to the buffer.
          delete[] pszOutBuffer;

          // This condition should never be reached since WinHttpQueryDataAvailable
          // reported that there are bits to read.
          if (!dwDownloaded)
              break;

      } while (dwSize > 0);
  }


  // Report any errors.

  // Close any open handles.
  if (hRequest) WinHttpCloseHandle(hRequest);
  if (hConnect) WinHttpCloseHandle(hConnect);
  if (hSession) WinHttpCloseHandle(hSession);

【问题讨论】:

  • 要么使用MultiByteToWideChar 将你的缓冲区转换为LPWSTR,要么使用MessageBoxA,并希望你所拥有的实际上没有任何真正的UTF-8。
  • @Mgetz:是的,这是我的错误。固定和工作。谢谢:)

标签: c++ winapi winhttprequest


【解决方案1】:

WinHttpReadData 读取原始数据,但您将其强制为 2 字节 WCHAR 的数组。我认为google在他们的页面上使用utf-8编码,所以你需要先转换它。

您的代码中的另一个问题是您没有设置终止 0:

...
else
{
    pszOutBuffer[ dwDownloaded ] = 0;
    MessageBox(hWnd, pszOutBuffer, "", NULL);
}

那么,检查new返回的值是没有意义的,因为new在失败的情况下会抛出异常。

【讨论】:

  • 实际上他确实设置了终止零,通过使用ZeroMemory正确初始化缓冲区
【解决方案2】:

我修好了:

MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);

到:

int wchars_num = MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, NULL, 0);
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, wstr, wchars_num);

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多