Win32应用程序中的WinHttpReadData无法正常工作

时间:2013-11-11 13:26:36

标签: c++ winapi winhttprequest

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

enter image description here

有什么想法吗?谢谢!
(响应文字可能包含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);

2 个答案:

答案 0 :(得分:2)

WinHttpReadData读取原始数据,但是你强制它是一个2字节WCHAR的数组。我认为谷歌在他们的网页上使用utf-8编码,所以你需要先转换它。

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

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

然后,检查new返回的值是没有意义的,因为new会在出现故障时抛出异常。

答案 1 :(得分:0)

我修好了:

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);