以下是一个使用C++实现HTTP文件下载的简单示例,其中使用了C++ 11的标准库和Boost库:

#include <iostream>
#include <fstream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main()
{
    try
    {
        boost::asio::io_service io_service;

        //获取URL信息和协议类型
        tcp::resolver resolver(io_service);
        tcp::resolver::query query("www.example.com", "http");
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

        //连接到服务器
        tcp::socket socket(io_service);
        boost::asio::connect(socket, endpoint_iterator);

        //构造HTTP请求消息
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
        request_stream << "GET /index.html HTTP/1.0\r\n";
        request_stream << "Host: www.example.com\r\n";
        request_stream << "Accept: */*\r\n";
        request_stream << "Connection: close\r\n\r\n";

        //发送HTTP请求消息
        boost::asio::write(socket, request);

        //读取HTTP响应消息
        boost::asio::streambuf response;
        boost::asio::read_until(socket, response, "\r\n");

        //检查响应是否正常
        std::istream response_stream(&response);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);

        if (!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            std::cout << "无效响应\n";
            return 1;
        }

        if (status_code != 200)
        {
            std::cout << "请求错误, 状态码: " << status_code << "\n";
            return 1;
        }

        //处理 HTTP 响应消息体
        boost::asio::read_until(socket, response, "\r\n\r\n");

        //找到Content-Length
        std::string header;
        while (std::getline(response_stream, header) && header != "\r")
        {
            if (header.find("Content-Length: ") == 0)
            {
                long long content_length = std::stoll(header.substr(16));
                std::cout << "文件大小为: " << content_length << " bytes.\n";

                //读取文件内容并写入本地文件
                std::ofstream output_file("example.html", std::ios::binary);
                if (!output_file)
                {
                    std::cout << "无法创建文件!\n";
                    return 1;
                }
                std::vector<char> buffer(1024*1024); //使用1MB缓冲区
                long long bytes_read = 0;
                while (bytes_read < content_length)
                {
                    long long read_length = std::min((long long)buffer.size(), content_length - bytes_read);
                    boost::asio::read(socket, boost::asio::buffer(buffer.data(), read_length));
                    output_file.write(buffer.data(), read_length);
                    bytes_read += read_length;
                }
                std::cout << "文件下载完成!\n";
                break;
            }
        }
    }
    catch (std::exception& e)
    {
        std::cout << "下载错误: " << e.what() << "\n";
        return 1;
    }

    return 0;
}

该程序会连接到“www.example.com”网站,请求“index.html”文件,在本地文件系统中保存该文件。可以根据实际需要修改相应的URL和文件名。

posted @ 2023-03-14 18:31  萧海~  阅读(343)  评论(0编辑  收藏  举报