</pre><p></p><pre code_snippet_id="326320" snippet_file_name="blog_20140521_2_4293343" name="code" class="cpp">// 使用Boost::Asio库, 实现Http的下载 // 使用Boost::Asio库, 不但可以实现下载, // 而且可以方便的实现断点续传.(以后会补充出来) // 驳壳地址: http://blog.csdn.net/robertkun #include "stdafx.h" #include <boost/asio.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/algorithm/string.hpp> #include <fstream> using boost::asio::ip::tcp; struct HttpResponse { public: explicit HttpResponse(){ clear();} std::string http_version; // 版本 unsigned int status_code; // 状态码 std::string status_message; // 状态 std::string header; // HTTP包头 std::string body; // HTTP返回的内容 std::string content_type; std::string modify_time; unsigned int content_length; unsigned int total_length; unsigned int offset; void clear() { http_version.clear(); status_code = -1; status_message.clear(); header.clear(); content_type.clear(); modify_time.clear(); content_length = 0; total_length = 0; offset = 0; body.clear(); } }; struct DownloadInfo { DownloadInfo() { id = 0; url.clear(); filename.clear(); md5.clear(); writesize = 0; continued = false; lasterr = 0; trycount = 0; } int id; std::string url; std::string filename; std::string md5; int writesize; bool continued; int lasterr; int trycount; }; // 获取文件 bool GetHttpFile(const std::string& szHost, const std::string& szParam) { DownloadInfo* d_diCurrent = new DownloadInfo(); d_diCurrent->filename = "DoLang.wma"; try { std::ofstream f_ofsSave; boost::asio::io_service io_serv; // Get a list of endpoints corresponding to the server name. std::string szService ("http"); std::string szIp = szHost; int i = szHost.find(":") ; if (i != -1) { szService = szHost.substr(i+1); szIp = szHost.substr(0, i); } tcp::resolver::query query(szIp, szService); tcp::resolver m_resolver(io_serv); tcp::socket s_socket(io_serv); tcp::resolver::iterator endpoint_iterator = m_resolver.resolve(query), end_it; // Try each endpoint until we successfully establish a connection. tcp::resolver::iterator it = boost::asio::connect(s_socket, endpoint_iterator); if(it == end_it) return false; boost::asio::streambuf request; { std::ostream request_stream(&request); request_stream << "GET " ; request_stream << szParam << " HTTP/1.1\r\n"; request_stream << "Host: " << szHost << "\r\n"; request_stream << "Accept: */*\r\n"; request_stream << "Pragma: no-cache\r\n"; request_stream << "Cache-Control: no-cache\r\n"; request_stream << "Connection: close\r\n"; request_stream << "\r\n"; boost::asio::write(s_socket, request); } // ************************************************************** // 取出数据 // ************************************************************** boost::asio::streambuf response; std::ostringstream packetStream; try { // Read until EOF, writing data to output as we go. bool hasReadHeader = false; boost::system::error_code error; HttpResponse result; result.body.clear(); while (boost::asio::read(s_socket, response, boost::asio::transfer_at_least(1), error)) { packetStream.str(""); packetStream << &response; std::string packetString = packetStream.str(); if (!hasReadHeader) { // 取出http header size_t nEndHeader = packetString.find("\r\n\r\n"); if(nEndHeader == std::string::npos) continue; hasReadHeader = true; result.header = packetString.substr(0, nEndHeader); // ***************************************************** // 分析文件头 // ***************************************************** // Check that response is OK. std::istringstream response_stream(result.header); response_stream >> result.http_version; response_stream >> result.status_code; std::string strLine; std::getline(response_stream, strLine); while (!strLine.empty()) { if (strLine.find("Content-Type:") != std::string::npos) { result.content_type = strLine.substr(strlen("Content-Type:")); result.content_type.erase(0, result.content_type.find_first_not_of(" ")); } if (strLine.find("Content-Length:") != std::string::npos) { result.content_length = atoi(strLine.substr(strlen("Content-Length:")).c_str()); result.total_length = result.content_length; } if (strLine.find("Last-Modified:") != std::string::npos) { result.modify_time = strLine.substr(strlen("Last-Modified:")); result.modify_time.erase(0, result.modify_time.find_first_not_of(" ")); } if (strLine.find("Content-Range: bytes") != std::string::npos) { std::string tmp = strLine.substr(strlen("Content-Range: bytes")); result.offset = atoi(tmp.substr(0, tmp.find('-')).c_str()); int ipos = tmp.find('/'); int ivalue = 0; if (ipos != std::string::npos) { ivalue = atoi(tmp.substr(ipos+1).c_str()); } if (ivalue) result.total_length = ivalue; } strLine.clear(); std::getline(response_stream, strLine); } if ( result.http_version.substr(0, 5) != "HTTP/") { std::cout << "Invalid response\n"; return false; } if (result.status_code != 200 && result.status_code != 206) { std::cout << "Response returned with status code " << result.status_code << "\n"; return false; } packetString.erase(0, nEndHeader + 4); } // ************************************************************** // 写入文件 // ************************************************************** { if (!f_ofsSave.is_open()) { std::string fn = d_diCurrent->filename; if (d_diCurrent->continued) { fn = d_diCurrent->filename+std::string(".td"); } { f_ofsSave.open(fn, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc ); } if (!f_ofsSave.is_open()) { return false; } d_diCurrent->writesize = 0; } try { f_ofsSave.write(packetString.c_str(), packetString.length()); d_diCurrent->writesize += packetString.length(); } catch (std::exception &e) { return false; } } } // 关闭文件 f_ofsSave.close(); if (error != boost::asio::error::eof) throw boost::system::system_error(error); } catch (std::exception& e) { std::cout << "Exception: " << e.what() << "\n"; return false; } } catch (std::exception& e) { std::cout << "Exception: " << e.what() << "\n"; return false; } return true; } // 获取网址对应的IP地址 bool GetHttpIp() { try { boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query("www.csdn.net", "http"); boost::system::error_code e; tcp::resolver::iterator iter = resolver.resolve(query, e); tcp::resolver::iterator end; while (iter != end) { tcp::endpoint ep = *iter++; std::cout<<ep<<std::endl; } } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return true; } int _tmain(int argc, _TCHAR* argv[]) { std::string szHost ("192.168.1.101"); std::string szParam("/DoDo/aishen.mp4"); GetHttpFile(szHost, szParam); //GetHttpIp(); system("pause"); return 0; }
添加boost链接库:
libboost_date_time-vc100-mt-gd-1_53.lib
libboost_regex-vc100-mt-gd-1_53.lib
libboost_system-vc100-mt-gd-1_53.lib