在网上找了很多文章,但基本都是说,C++发送HTTP请求可以,但谈到具体方法,就众说众说纷纭了。具体说来,有IXMLHTTPRequest2、curl、POCO,当然还有用socket、Windows API的方法。这些方法中,除了socket外,我都尝试过。
首先我用的是curl,需要先编译,编译完成后,就可以用curl_xxx的函数来发送和接收请求了,但是马上我就发现了一个问题,必须使用动态链接库才能运行,即使我编译好了静态库,还指定了/MT(而不是/MD),也不行。非常的尴尬,本来应该是一个跨平台的完美解决方案,但就因为这样一个愚蠢的原因,就没探索了。
然后我尝试使用COM组件,需要用到<MsXml6.h>头文件和<MsXml6.lib>库,网上有IXMLHTTPRequest2的例子,但例子是Windows Store上的应用,语法也是C++/CX,部分代码还用到了.NET里面的东西(虽然我相信可以不需要.NET),移植了一阵子后,感觉很麻烦,就换方法了。
再然后我发现POCO库可以解决这个问题,当准备用POCO库的时候,发现也需要编译,就想到了以前编译curl和gmp后的结果(静态库总有这样或那样的问题,动态库正常),然后直接没信心再试了。
最后我使用了Windows API,用的<winhttp.h>头文件,配合使用winhttp.lib库,成功,而且感觉,只需封装一下,这是我想要的方法:
// CppConsole.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <winhttp.h> #pragma comment(lib, "winhttp") using namespace std; void do_work(); int _tmain(int argc, _TCHAR* argv[]) { _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); do_work(); } void do_work() { DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; 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"baidu.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest(hConnect, L"GET", L"", 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, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); // Continue to verify data until there is nothing left. if (bResults) { do { // Verify available data. dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) printf("Error %u in WinHttpReadData.\n", GetLastError()); else printf("%s\n", pszOutBuffer); // Free the memory allocated to the buffer. delete[] pszOutBuffer; } while (dwSize > 0); } // Report errors. if (!bResults) printf("Error %d has occurred.\n", GetLastError()); // Close open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); }