c++实现mp3

c++ 实现 http_mp4

  • 🔴 1、c++ 实现 http_mp4

    • 🟢 1.1、步骤 1:选择合适的库
      首先,你需要选择一个可以帮助你创建 HTTP 服务器的库。有一些流行的选择包括:

      Boost.Asio - 一个强大的 C++库,用于进行网络和底层 I/O 编程,通常结合 Boost.Beast 来处理 HTTP 协议。
      Poco - 一个 C++网络编程库,其中包含了用于建立 HTTP 服务器的组件。
      CppRestSDK (又称 Casablanca) - 提供了一个高级 HTTP 客户端和服务器,可以处理 REST 调用。

    • 🟢 1.2、设置 HTTP 服务器

    使用你选择的库来设置一个 HTTP 服务器。这通常包括配置监听端口,处理连接和请求,并设置路由。

    • 🟢 1.3、处理 HTTP 请求
      当收到一个请求时,需要检查请求 URL 是否对应于一个有效的 MP4 文件。如果是,则需要打开该文件并准备传输。

    • 🟢 1.4、传输 MP4 数据
      由于 MP4 是一个二进制文件,你需要以二进制模式读取文件,并通过 HTTP 响应将其发送给客户端。根据客户端的需求,可能还需要支持范围请求(Range Requests)以实现视频的随机访问。

    • 🟢 1.5、处理 Range 请求
      如果客户端请求特定的字节范围(这在视频流中很常见),服务器需要返回请求范围内的数据,并在 HTTP 响应中设置适当的状态码(206 Partial Content)和头信息(如 Content-Range)。

代码示例(使用 Boost.Beast 和 Boost.Asio):

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio.hpp>
#include <fstream>
#include <string>

namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = net::ip::tcp;               // from <boost/asio/ip/tcp.hpp>

// 处理HTTP请求并返回相应的HTTP响应
void handle_request(const http::request<http::string_body>& req, http::response<http::vector_body<char>>& res, const std::string& file_path) {
    std::ifstream is{file_path, std::ios::in | std::ios::binary};

    // 判断文件是否存在和可读
    if(!is) {
        res.result(http::status::not_found);
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "text/html");
        res.keep_alive(req.keep_alive());
        res.body() = "The resource could not be found.";
        return;
    }

    // 将文件内容读取到响应体中
    std::vector<char> buffer((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());

    // 设置响应信息
    res.result(http::status::ok);
    res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
    res.set(http::field::content_type, "video/mp4");
    res.body() = std::move(buffer);
    res.prepare_payload();
    res.keep_alive(req.keep_alive());
}

int main() {
    try {
        auto const address = net::ip::make_address("127.0.0.1");
        auto const port = static_cast<unsigned short>(8080);

        net::io_context ioc{1};            // ASIO的I/O上下文

        tcp::acceptor acceptor{ioc, {address, port}}; // 接受新连接的TCP接收器
        tcp::socket socket{ioc};           // TCP套接字

        while(true) {
            acceptor.accept(socket);       // 等待并接受新连接

            beast::flat_buffer buffer;     // 用于读取请求的缓冲区
            http::request<http::string_body> req;

            http::read(socket, buffer, req);  // 读取请求

            http::response<http::vector_body<char>> res;
            handle_request(req, res, "./video.mp4");   // 处理请求并准备响应

            http::write(socket, res);      // 发送响应

            socket.shutdown(tcp::socket::shutdown_send); // 关闭套接字发送端
            socket.close();                 // 关闭连接
        }
    } catch(const std::exception& e) {
        std::cerr << "Server error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}


我说了没 head 之后
#include <boost/beast.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <fstream>
#include <string>

namespace beast = boost::beast;         // 来自 <boost/beast.hpp>
namespace http = beast::http;           // 来自 <boost/beast/http.hpp>
namespace net = boost::asio;            // 来自 <boost/asio.hpp>
namespace fs = boost::filesystem;       // 来自 <boost/filesystem.hpp>
using tcp = net::ip::tcp;               // 来自 <boost/asio/ip/tcp.hpp>

// 读取文件并发送HTTP响应
void handle_request(const http::request<http::string_body>& req,
                    http::response<http::vector_body<char>>& res,
                    const std::string& file_path) {
    std::ifstream is(file_path, std::ios::binary | std::ios::ate);
    if (!is) {
        // 文件未找到,返回404 Not Found
        res = http::response<http::string_body>(http::status::not_found, req.version());
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "text/html");
        res.keep_alive(req.keep_alive());
        res.body() = "File not found\r\n";
        res.prepare_payload();
        return;
    }

    // 获取文件大小
    auto const size = is.tellg();
    is.seekg(0);

    // 设置响应属性
    res.result(http::status::ok);
    res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
    res.set(http::field::content_type, "video/mp4");
    res.content_length(size); // 设置内容长度

    // 读取文件内容到响应体
    res.body().resize(static_cast<size_t>(size));
    is.read(res.body().data(), size);

    // 发送响应
    res.prepare_payload();
}

int main() {
    try {
        auto const address = net::ip::make_address("0.0.0.0");
        auto const port = static_cast<unsigned short>(8080);

        net::io_context ioc;

        tcp::acceptor acceptor{ioc, {address, port}};
        tcp::socket socket{ioc};

        while (true) {
            acceptor.accept(socket);

            beast::flat_buffer buffer;

            // 解析HTTP请求
            http::request<http::string_body> req;
            http::read(socket, buffer, req);

            // 创建HTTP响应
            http::response<http::vector_body<char>> res;
            handle_request(req, res, "./video.mp4");

            // 发送HTTP响应
            http::write(socket, res);

            // 关闭套接字
            beast::error_code ec;
            socket.shutdown(tcp::socket::shutdown_both, ec);
            if (ec && ec != beast::errc::not_connected) {
                std::cerr << "Socket shutdown error: " << ec.message() << std::endl;
            }
            socket.close(ec);
        }
    } catch (const std::exception& e) {
        std::cerr << "Server error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

posted @ 2023-12-25 14:52  郭杰前端开发  阅读(48)  评论(0编辑  收藏  举报
## 希望内容对你有帮助,如果有错误请联系我 q: 1911509826,感谢支持