在網上找了很多文章,但基本都是說,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); }