最近一直在看有关Http的知识,对其基本的理论知识已经有所掌握,想通过一个C++具体的例子进行实际操作。。于是上网查找了很多资料,发现在Windows系统上,可以通过WinHttp API接口开啊Http,于是仿照网上例子编写一个获取网页源码的C++程序。其中的代码基本是copy网友,主要是自己对代码的理解,并以此作为入门。
例子代码如下:
1 // WinHttpTest.cpp : 定义控制台应用程序的入口点。 2 // 3 //#include <stdafx.h> 4 #include <vector> 5 #include <winsock2.h> 6 #include <Winhttp.h> 7 //#include <urlmon.h> 8 #include <windows.h> 9 #include <iostream> 10 #include <fstream> 11 #include <string> 12 #include "AtlBase.h" 13 #include "AtlConv.h" 14 using namespace std; 15 #pragma comment(lib, "winhttp")//这一句不能省略 16 string GetHost(string strUrl) 17 { 18 int indexHttp = strUrl.find("http://"); 19 if(indexHttp != -1) 20 { 21 strUrl = strUrl.substr(7); 22 } 23 else 24 return ""; 25 int indexSlash = strUrl.find("/"); 26 if(indexSlash != -1) 27 { 28 return strUrl.substr(0, indexSlash); 29 } 30 else 31 return strUrl; 32 return ""; 33 } 34 string GetRequestStr(string strUrl) 35 { 36 int indexHttp = strUrl.find("http://"); 37 if(indexHttp != -1) 38 { 39 strUrl = strUrl.substr(7); 40 } 41 else 42 return ""; 43 int indexSlash = strUrl.find("/"); 44 if(indexSlash == -1) 45 { 46 return ""; 47 } 48 else 49 return strUrl.substr(indexSlash); 50 } 51 string GetHtml(string strUrl) 52 { 53 string strHost = GetHost(strUrl);//获取Host 54 string strRequestStr = GetRequestStr(strUrl);//获取请求路径 55 USES_CONVERSION; 56 //2014年7月9日10:02:29 57 //LPCWSTR的定义 typedef const wchar_t* LPCWSTR; 58 //LPSTR的定义 typedef char* LPCWSTR; 59 //LPWSTR的定义 typedef wchar_t* LPWSTR; 60 LPCWSTR host = A2CW(strHost.c_str());//string转换为常量指针类型 61 LPCWSTR requestStr = A2CW(strRequestStr.c_str()); 62 //Variables 63 DWORD dwSize = 0; 64 DWORD dwDownloaded = 0; 65 LPSTR pszOutBuffer; 66 vector <string> vFileContent; 67 BOOL bResults = FALSE; 68 69 //Note the definition of HINTERNET 70 HINTERNET hSession = NULL, 71 hConnect = NULL, 72 hRequest = NULL; 73 string strHtml = "";// store the html code 74 string str;//temporary variables 75 ofstream out("test.html",ios::binary);//output the html code to a html text; 76 //2014年7月9日10:39:33 77 //Search the WinHttp API 78 //what to do when call the function WinHttpOpen? 79 // Use WinHttpOpen to obtain a session handle. 80 hSession = WinHttpOpen(L"WinHTTP Example/1.0", 81 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 82 WINHTTP_NO_PROXY_NAME, 83 WINHTTP_NO_PROXY_BYPASS, 0); 84 // Specify an HTTP server. 85 if (hSession) 86 hConnect = WinHttpConnect(hSession, host, 87 INTERNET_DEFAULT_HTTP_PORT, 0); 88 // Create an HTTP request handle. 89 if (hConnect) 90 hRequest = WinHttpOpenRequest(hConnect, L"GET", requestStr, 91 NULL, WINHTTP_NO_REFERER, 92 NULL, 93 NULL); 94 // Send a request. 95 if (hRequest) 96 bResults = WinHttpSendRequest(hRequest, 97 WINHTTP_NO_ADDITIONAL_HEADERS, 98 0, WINHTTP_NO_REQUEST_DATA, 0, 99 0, 0); 100 // End the request. 101 if (bResults) 102 bResults = WinHttpReceiveResponse(hRequest, NULL); 103 104 //obtain the html source code 105 if (bResults) 106 do 107 { 108 // Check for available data. 109 dwSize = 0; 110 if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) 111 printf( "Error %u in WinHttpQueryDataAvailable.\n", 112 GetLastError()); 113 // Allocate space for the buffer. 114 pszOutBuffer = new char[dwSize+1]; 115 if (!pszOutBuffer) 116 { 117 printf("Out of memory\n"); 118 dwSize=0; 119 } 120 else 121 { 122 // Read the Data. 123 ZeroMemory(pszOutBuffer, dwSize+1); 124 if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 125 dwSize, &dwDownloaded)) 126 { 127 printf( "Error %u in WinHttpReadData.\n", 128 GetLastError()); 129 } 130 else 131 { 132 //printf("%s", pszOutBuffer); 133 // Data in vFileContent 134 vFileContent.push_back(pszOutBuffer); 135 136 } 137 // Free the memory allocated to the buffer. 138 delete [] pszOutBuffer; 139 } 140 } while (dwSize>0); 141 // Keep checking for data until there is nothing left. 142 // Report any errors. 143 if (!bResults) 144 printf("Error %d has occurred.\n",GetLastError()); 145 // Close any open handles. 146 if (hRequest) WinHttpCloseHandle(hRequest); 147 if (hConnect) WinHttpCloseHandle(hConnect); 148 if (hSession) WinHttpCloseHandle(hSession); 149 150 for(int i=0;i<(int)vFileContent.size();i++) 151 { 152 str=vFileContent[i]; 153 out<<str; 154 strHtml += vFileContent[i]; 155 } 156 out.close(); 157 return strHtml; 158 } 159 int _tmain(int argc, _TCHAR* argv[]) 160 { 161 162 string str = GetHtml("http://bbs.bccn.net/thread-294526-1-1.html"); 163 //output the html code 164 //cout << str << endl; 165 system("pause"); 166 return 0; 167 }
执行后,可以双击tes.html文件运行,也可打开这个文件与通过浏览器打开的网页源码就行对比。。