跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

HTTP 协议深度解析(三):完整 HTTP 服务器实现

综述由AI生成HTTP 协议深度解析系列第三篇,重点讲解完整 HTTP 服务器的 C++ 实现。内容涵盖 Web 根目录概念与路径映射规则、文件读取与 MIME 类型判断、HTTP 请求解析(首行、Header、Body、参数)、响应构造(状态码、Header、Body)。通过 HttpServer 类展示 Socket 通信、多线程处理连接及静态资源服务。最后对比了 HTTP 0.9 至 3.0 的版本演进特性。掌握该实现有助于深入理解网络编程与 Web 通信基础。

奇形怪状发布于 2026/2/27更新于 2026/5/3126 浏览
HTTP 协议深度解析(三):完整 HTTP 服务器实现

HTTP 协议深度解析(三):完整 HTTP 服务器实现

一、web 根目录的概念

1.1 什么是 web 根目录

**web 根目录(Document Root)**是 HTTP 服务器存放网页文件的目录。

示例:

web 根目录:/var/www/html 目录结构: /var/www/html/ ├── index.html ├── about.html ├── css/ │ └── style.css ├── js/ │ └── app.js └── images/ └── logo.png 

URL 映射:

http://example.com/ → /var/www/html/index.html http://example.com/about.html → /var/www/html/about.html http://example.com/css/style.css → /var/www/html/css/style.css http://example.com/images/logo.png → /var/www/html/images/logo.png 

1.2 路径映射规则

规则:URL 路径 = web 根目录 + URL 路径部分

std::string GetFilePath(const std::string& url_path, const std::string& web_root) {
    if (url_path == "/") {
        return web_root + "/index.html"; // 默认首页
    }
    return web_root + url_path;
}

示例:

web 根目录:./wwwroot URL:/test.html 文件路径:./wwwroot/test.html URL:/images/photo.jpg 文件路径:./wwwroot/images/photo.jpg 

1.3 安全性考虑

路径穿越攻击(Path Traversal):

恶意请求:

GET /../../../etc/passwd HTTP/1.1 

如果不检查,会访问到:

./wwwroot/../../../etc/passwd → /etc/passwd 

泄露了系统敏感文件!

防御措施:

bool IsSafePath(const std::string& path, const std::string& web_root) {
    // 1. 检查是否包含".."
    if (path.find("..") != std::string::npos) {
        return false;
    }
    // 2. 检查是否在 web 根目录下
    char real_path[PATH_MAX];
    if (realpath(path.c_str(), real_path) == NULL) {
        return false;
    }
    char real_root[PATH_MAX];
    realpath(web_root.c_str(), real_root);
    // 检查 real_path 是否以 real_root 开头
    return strncmp(real_path, real_root, strlen(real_root)) == 0;
}

二、文件读取与 MIME 类型

2.1 读取文件内容

std::string ReadFile(const std::string& filepath) {
    std::ifstream file(filepath, std::ios::binary);
    if (!file.is_open()) {
        return "";
    }
    // 移动到文件末尾,获取文件大小
    file.seekg(0, std::ios::end);
    size_t filesize = file.tellg();
    // 回到文件开头
    file.seekg(0, std::ios::beg);
    // 读取内容
    std::string content;
    content.resize(filesize);
    file.read(&content[0], filesize);
    file.close();
    return content;
}

关键点:

  • std::ios::binary:二进制模式,避免文本模式的换行符转换
  • seekg和 tellg:获取文件大小
  • resize:预分配内存,提高效率
  • read:读取指定字节数

2.2 MIME 类型判断

MIME(Multipurpose Internet Mail Extensions)类型用于标识文件的媒体类型。

浏览器根据 Content-Type 判断如何处理响应内容:

  • text/html:渲染 HTML
  • image/png:显示图片
  • application/json:解析 JSON
  • text/plain:显示纯文本

根据文件扩展名判断 MIME 类型:

std::string GetMimeType(const std::string& filepath) {
    // 提取扩展名
    size_t pos = filepath.rfind('.');
    if (pos == std::string::npos) {
        return "application/octet-stream"; // 默认二进制流
    }
    std::string ext = filepath.substr(pos);
    // MIME 类型映射表
    static std::map<std::string, std::string> mime_types = {
        {".html", "text/html"},
        {".htm", "text/html"},
        {".css", "text/css"},
        {".js", "application/javascript"},
        {".json", "application/json"},
        {".xml", "application/xml"},
        {".txt", "text/plain"},
        {".jpg", "image/jpeg"},
        {".jpeg", "image/jpeg"},
        {".png", "image/png"},
        {".gif", "image/gif"},
        {".svg", "image/svg+xml"},
        {".ico", "image/x-icon"},
        {".pdf", "application/pdf"},
        {".zip", "application/zip"},
        {".mp3", "audio/mpeg"},
        {".mp4", "video/mp4"}
    };
    auto it = mime_types.find(ext);
    if (it != mime_types.end()) {
        return it->second;
    }
    return "application/octet-stream";
}

2.3 文件是否存在

bool FileExists(const std::string& filepath) {
    struct stat info;
    return stat(filepath.c_str(), &info) == 0 && S_ISREG(info.st_mode);
}

stat函数:获取文件信息。

S_ISREG宏:判断是否为普通文件(不是目录、链接等)。

三、HTTP 请求解析

3.1 请求结构体

定义一个结构体存储解析后的 HTTP 请求:

struct HttpRequest {
    std::string method; // 方法:GET、POST 等
    std::string url; // URL 路径
    std::string version; // HTTP 版本
    std::map<std::string, std::string> headers; // Header 键值对
    std::string body; // Body 内容
    // GET 参数(从 URL 解析)
    std::map<std::string, std::string> query_params;
    // POST 参数(从 Body 解析,application/x-www-form-urlencoded)
    std::map<std::string, std::string> post_params;
};

3.2 解析首行

bool ParseRequestLine(const std::string& line, HttpRequest* req) {
    std::istringstream iss(line);
    iss >> req->method >> req->url >> req->version;
    if (req->method.empty() || req->url.empty() || req->version.empty()) {
        return false;
    }
    return true;
}
bool ParseHeader(const std::string& line, HttpRequest* req) {
    size_t pos = line.find(':');
    if (pos == std::string::npos) {
        return false;
    }
    std::string key = line.substr(0, pos);
    std::string value = line.substr(pos + 1);
    // 去除 value 前面的空格
    size_t start = value.find_first_not_of(' ');
    if (start != std::string::npos) {
        value = value.substr(start);
    }
    req->headers[key] = value;
    return true;
}

示例:

输入:"Host: www.example.com" 解析:headers["Host"]="www.example.com"

3.4 完整解析流程

bool ParseHttpRequest(const std::string& raw_request, HttpRequest* req) {
    std::istringstream stream(raw_request);
    std::string line;
    // 1. 解析首行
    if (!std::getline(stream, line)) {
        return false;
    }
    // 去除\r
    if (!line.empty() && line.back() == '\r') {
        line.pop_back();
    }
    if (!ParseRequestLine(line, req)) {
        return false;
    }
    // 2. 解析 Header
    while (std::getline(stream, line)) {
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        // 空行表示 Header 结束
        if (line.empty()) {
            break;
        }
        ParseHeader(line, req);
    }
    // 3. 读取 Body
    std::string body_line;
    while (std::getline(stream, body_line)) {
        req->body += body_line;
        if (stream.peek() != EOF) {
            req->body += "\n";
        }
    }
    return true;
}

3.5 解析 URL 参数

URL 格式:/search?keyword=Linux&page=2

void ParseQueryParams(HttpRequest* req) {
    size_t pos = req->url.find('?');
    if (pos == std::string::npos) {
        return; // 没有查询参数
    }
    std::string query = req->url.substr(pos + 1);
    req->url = req->url.substr(0, pos); // 去除查询参数部分
    // 解析 key1=value1&key2=value2
    std::istringstream stream(query);
    std::string pair;
    while (std::getline(stream, pair, '&')) {
        size_t eq = pair.find('=');
        if (eq != std::string::npos) {
            std::string key = pair.substr(0, eq);
            std::string value = pair.substr(eq + 1);
            req->query_params[key] = UrlDecode(value);
        }
    }
}

3.6 urldecode 实现

std::string UrlDecode(const std::string& str) {
    std::string result;
    for (size_t i = 0; i < str.size(); ++i) {
        if (str[i] == '%' && i + 2 < str.size()) {
            // %XX 格式
            int value;
            std::istringstream iss(str.substr(i + 1, 2));
            if (iss >> std::hex >> value) {
                result += static_cast<char>(value);
                i += 2;
            } else {
                result += str[i];
            }
        } else if (str[i] == '+') {
            result += ' '; // +号表示空格
        } else {
            result += str[i];
        }
    }
    return result;
}

示例:

输入:"C%2B%2B%20%E7%BC%96%E7%A8%8B" 输出:"C++ 编程"

3.7 解析 POST 参数

void ParsePostParams(HttpRequest* req) {
    if (req->method != "POST") {
        return;
    }
    // 只处理 application/x-www-form-urlencoded
    auto it = req->headers.find("Content-Type");
    if (it == req->headers.end() || it->second.find("application/x-www-form-urlencoded") == std::string::npos) {
        return;
    }
    // Body 格式:key1=value1&key2=value2
    std::istringstream stream(req->body);
    std::string pair;
    while (std::getline(stream, pair, '&')) {
        size_t eq = pair.find('=');
        if (eq != std::string::npos) {
            std::string key = pair.substr(0, eq);
            std::string value = pair.substr(eq + 1);
            req->post_params[key] = UrlDecode(value);
        }
    }
}

四、HTTP 响应构造

4.1 响应结构体

struct HttpResponse {
    std::string version; // HTTP/1.1
    int status_code; // 200、404 等
    std::string status_text; // OK、Not Found 等
    std::map<std::string, std::string> headers; // 响应头
    std::string body; // 响应体

    std::string Build() {
        std::ostringstream oss;
        // 首行
        oss << version << " " << status_code << " " << status_text << "\r\n";
        // Header
        for (auto& pair : headers) {
            oss << pair.first << ": " << pair.second << "\r\n";
        }
        // 空行
        oss << "\r\n";
        // Body
        oss << body;
        return oss.str();
    }
};

4.2 状态码对应的文本

std::string GetStatusText(int code) {
    static std::map<int, std::string> status_texts = {
        {200, "OK"},
        {201, "Created"},
        {204, "No Content"},
        {301, "Moved Permanently"},
        {302, "Found"},
        {304, "Not Modified"},
        {400, "Bad Request"},
        {401, "Unauthorized"},
        {403, "Forbidden"},
        {404, "Not Found"},
        {500, "Internal Server Error"},
        {502, "Bad Gateway"},
        {503, "Service Unavailable"}
    };
    auto it = status_texts.find(code);
    if (it != status_texts.end()) {
        return it->second;
    }
    return "Unknown";
}

4.3 构造 200 响应

HttpResponse Build200Response(const std::string& content, const std::string& content_type) {
    HttpResponse resp;
    resp.version = "HTTP/1.1";
    resp.status_code = 200;
    resp.status_text = "OK";
    resp.headers["Content-Type"] = content_type;
    resp.headers["Content-Length"] = std::to_string(content.size());
    resp.headers["Connection"] = "close";
    resp.body = content;
    return resp;
}

4.4 构造 404 响应

HttpResponse Build404Response() {
    std::string html = "<html>\n"
                       "<head><title>404 Not Found</title></head>\n"
                       "<body>\n"
                       "<h1>404 Not Found</h1>\n"
                       "<p>The requested resource was not found on this server.</p>\n"
                       "</body>\n"
                       "</html>";
    HttpResponse resp;
    resp.version = "HTTP/1.1";
    resp.status_code = 404;
    resp.status_text = "Not Found";
    resp.headers["Content-Type"] = "text/html";
    resp.headers["Content-Length"] = std::to_string(html.size());
    resp.body = html;
    return resp;
}

五、完整 HTTP 服务器实现

5.1 HttpServer 类

class HttpServer {
public:
    HttpServer(int port, const std::string& web_root)
        : _port(port), _web_root(web_root), _listen_fd(-1) {}

    bool Start() {
        // 创建 socket
        _listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listen_fd < 0) {
            perror("socket");
            return false;
        }
        // 设置端口复用
        int opt = 1;
        setsockopt(_listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
        // bind
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(_port);
        if (bind(_listen_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
            perror("bind");
            return false;
        }
        // listen
        if (listen(_listen_fd, 10) < 0) {
            perror("listen");
            return false;
        }
        std::cout << "HTTP Server started on port " << _port << std::endl;
        std::cout << "Web root: " << _web_root << std::endl;
        // accept 循环
        while (true) {
            struct sockaddr_in client_addr;
            socklen_t len = sizeof(client_addr);
            int client_fd = accept(_listen_fd, (struct sockaddr*)&client_addr, &len);
            if (client_fd < 0) {
                perror("accept");
                continue;
            }
            // 创建线程处理连接,这只是'教学版:一连接一线程',实际'工程版:线程池 + 任务队列 / epoll + reactor'
            std::thread t(&HttpServer::HandleClient, this, client_fd);
            t.detach();
        }
        return true;
    }

private:
    void HandleClient(int client_fd) {
        // 读取请求
        char buffer[8192];
        ssize_t n = read(client_fd, buffer, sizeof(buffer) - 1);
        if (n <= 0) {
            close(client_fd);
            return;
        }
        buffer[n] = '\0';
        std::string raw_request(buffer);
        // 解析请求
        HttpRequest req;
        if (!ParseHttpRequest(raw_request, &req)) {
            close(client_fd);
            return;
        }
        ParseQueryParams(&req);
        ParsePostParams(&req);
        // 打印日志
        std::cout << req.method << " " << req.url << std::endl;
        // 处理请求
        HttpResponse resp = ProcessRequest(req);
        // 发送响应
        std::string response_str = resp.Build();
        write(client_fd, response_str.c_str(), response_str.size());
        close(client_fd);
    }

    HttpResponse ProcessRequest(const HttpRequest& req) {
        // 处理静态资源
        if (req.method == "GET") {
            return HandleStaticFile(req);
        }
        // 处理 POST 请求
        if (req.method == "POST") {
            return HandlePostRequest(req);
        }
        // 不支持的方法
        return Build404Response();
    }

    HttpResponse HandleStaticFile(const HttpRequest& req) {
        std::string filepath = _web_root + req.url;
        // 默认首页
        if (req.url == "/") {
            filepath = _web_root + "/index.html";
        }
        // 检查文件是否存在
        if (!FileExists(filepath)) {
            return Build404Response();
        }
        // 读取文件
        std::string content = ReadFile(filepath);
        if (content.empty()) {
            return Build404Response();
        }
        // 判断 MIME 类型
        std::string mime_type = GetMimeType(filepath);
        // 构造响应
        return Build200Response(content, mime_type);
    }

    HttpResponse HandlePostRequest(const HttpRequest& req) {
        // 示例:处理/api/echo 接口
        if (req.url == "/api/echo") {
            std::string json = "{\"received\": \"" + req.body + "\"}";
            return Build200Response(json, "application/json");
        }
        return Build404Response();
    }

    int _port;
    std::string _web_root;
    int _listen_fd;
};

5.2 main 函数

int main(int argc, char* argv[]) {
    if (argc != 3) {
        std::cout << "Usage: " << argv[0] << " <port> <web_root>" << std::endl;
        return 1;
    }
    int port = std::atoi(argv[1]);
    std::string web_root = argv[2];
    HttpServer server(port, web_root);
    server.Start();
    return 0;
}

六、测试验证

6.1 准备测试文件

创建 web 根目录:

mkdir -p wwwroot 

创建 wwwroot/index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页面</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>欢迎访问 HTTP 服务器</h1>
<p>这是一个静态 HTML 页面</p>
<img src="/logo.png" alt="Logo">
<script src="/app.js"></script>
</body>
</html>

创建 wwwroot/style.css:

body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    margin: 50px;
}
h1 {
    color: #333;
}

创建 wwwroot/app.js:

console.log('JavaScript loaded!');
alert('Hello from HTTP Server!');

6.2 编译运行

g++ -o http_server http_server.cpp -std=c++11 -lpthread
./http_server 9090 ./wwwroot 

输出:

HTTP Server started on port 9090 Web root: ./wwwroot 

6.3 浏览器测试

打开浏览器,访问:

http://127.0.0.1:9090/ 

浏览器显示 index.html 内容,并自动加载了 CSS 和 JS 文件。

服务器端日志:

GET / GET /style.css GET /app.js GET /logo.png GET /favicon.ico 

6.4 curl 测试

测试 GET 请求:

curl -i http://127.0.0.1:9090/

返回:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 285
Connection: close
<!DOCTYPE html><html>... </html>

测试 404:

curl -i http://127.0.0.1:9090/nonexistent.html

返回:

HTTP/1.1 404 Not Found
Content-Type: text/html
Content-Length: 158
<html><head><title>404 Not Found</title></head>... </html>

测试 GET 参数:

curl -i "http://127.0.0.1:9090/search?keyword=Linux&page=2"

服务器端解析出:

query_params["keyword"]="Linux" query_params["page"]="2"

测试 POST 请求:

curl -X POST http://127.0.0.1:9090/api/echo \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=123"

七、HTTP 版本演进

7.1 HTTP/0.9(1991 年)

特点:

  • 只支持 GET 方法
  • 只能传输 HTML
  • 无 Header
  • 连接立即关闭

示例:

请求:GET /index.html 响应:<html>...</html>

7.2 HTTP/1.0(1996 年)

新增特性:

  • 支持 POST、HEAD 方法
  • 引入 Header(可以传输多种数据类型)
  • 状态码
  • 缓存机制

缺陷:

  • 每次请求都要建立新的 TCP 连接(短连接)
  • 性能差

7.3 HTTP/1.1(1999 年)

新增特性:

  • 持久连接(Connection: keep-alive)
  • 管道化(Pipelining)
  • Host 字段(虚拟主机)
  • 分块传输编码(Chunked Transfer Encoding)

优势:

  • 复用 TCP 连接,减少握手开销
  • 一个连接可以发送多个请求

缺陷:

  • 队头阻塞(Head-of-Line Blocking)
  • Header 冗余(每次请求都要发送完整 Header)

7.4 HTTP/2.0(2015 年)

核心技术:

  • 多路复用(Multiplexing):一个 TCP 连接上并行处理多个请求
  • 二进制帧(Binary Framing):效率更高
  • Header 压缩(HPACK 算法)
  • 服务器推送(Server Push)

优势:

  • 解决了 HTTP/1.1 的队头阻塞问题
  • 显著提高性能

时代背景:

  • 移动互联网兴起
  • 网页越来越复杂(大量静态资源)

7.5 HTTP/3.0(2022 年)

核心技术:

  • 基于 QUIC 协议(Quick UDP Internet Connections)
  • QUIC 基于 UDP,而不是 TCP
  • 减少连接建立时间
  • 解决 TCP 的队头阻塞问题

优势:

  • 连接建立更快(0-RTT 或 1-RTT)
  • 更好的移动网络适应性
  • 连接迁移(IP 地址变化时连接不断)

八、本篇总结

8.1 核心要点

web 根目录:

  • 存放网页文件的目录
  • URL 路径映射到文件系统路径
  • 注意路径穿越攻击

文件读取:

  • 二进制模式读取
  • seekg/tellg 获取文件大小
  • resize 预分配内存

MIME 类型:

  • 根据文件扩展名判断
  • 告诉浏览器如何处理响应内容
  • 常见类型:text/html、image/png、application/json 等

HTTP 请求解析:

  • 首行:方法 URL 版本
  • Header:键值对
  • Body:可选
  • GET 参数从 URL 解析
  • POST 参数从 Body 解析

HTTP 响应构造:

  • 首行:版本 状态码 状态描述
  • Header:Content-Type、Content-Length 等
  • Body:HTML、JSON、图片等

完整服务器:

  • socket→bind→listen→accept 循环
  • 多线程处理连接
  • 解析请求→路由分发→构造响应→发送
  • 静态资源服务
  • 动态 API 处理

HTTP 版本演进:

  • HTTP/0.9:最简单,只有 GET
  • HTTP/1.0:引入 Header、状态码
  • HTTP/1.1:持久连接、管道化
  • HTTP/2.0:多路复用、二进制帧、Header 压缩
  • HTTP/3.0:基于 QUIC(UDP)、更快的连接建立

8.2 容易混淆的点

  1. web 根目录和文件路径:URL 的/对应 web 根目录,不是系统根目录。
  2. MIME 类型的重要性:Content-Type 错误会导致浏览器无法正确显示内容(如图片显示为乱码)。
  3. GET 参数和 POST 参数的位置:GET 在 URL,POST 在 Body。
  4. urldecode 的必要性:URL 中的中文、特殊字符都是编码后的,必须 decode 才能正确处理。
  5. HTTP/1.1 的持久连接:默认就是 keep-alive,不需要显式设置。只有想关闭时才设置 Connection: close。
  6. HTTP/2 和 HTTP/3 的区别:HTTP/2 基于 TCP,HTTP/3 基于 UDP(QUIC 协议)。

目录

  1. HTTP 协议深度解析(三):完整 HTTP 服务器实现
  2. 一、web 根目录的概念
  3. 1.1 什么是 web 根目录
  4. 1.2 路径映射规则
  5. 1.3 安全性考虑
  6. 二、文件读取与 MIME 类型
  7. 2.1 读取文件内容
  8. 2.2 MIME 类型判断
  9. 2.3 文件是否存在
  10. 三、HTTP 请求解析
  11. 3.1 请求结构体
  12. 3.2 解析首行
  13. 3.4 完整解析流程
  14. 3.5 解析 URL 参数
  15. 3.6 urldecode 实现
  16. 3.7 解析 POST 参数
  17. 四、HTTP 响应构造
  18. 4.1 响应结构体
  19. 4.2 状态码对应的文本
  20. 4.3 构造 200 响应
  21. 4.4 构造 404 响应
  22. 五、完整 HTTP 服务器实现
  23. 5.1 HttpServer 类
  24. 5.2 main 函数
  25. 六、测试验证
  26. 6.1 准备测试文件
  27. 6.2 编译运行
  28. 6.3 浏览器测试
  29. 6.4 curl 测试
  30. 七、HTTP 版本演进
  31. 7.1 HTTP/0.9(1991 年)
  32. 7.2 HTTP/1.0(1996 年)
  33. 7.3 HTTP/1.1(1999 年)
  34. 7.4 HTTP/2.0(2015 年)
  35. 7.5 HTTP/3.0(2022 年)
  36. 八、本篇总结
  37. 8.1 核心要点
  38. 8.2 容易混淆的点
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • VS Code 远程连接服务器后 GitHub Copilot 无法使用
  • VS Code 集成 GitHub Copilot 使用指南
  • C++ 虚函数与纯虚函数:多态的核心实现基石
  • AI 大模型本地离线部署指南:GPT4All、LM Studio 与 Ollama 方案详解
  • 微信支付商家转账常见问题及 Java 调用示例
  • 基于高阶控制障碍函数的端到端无人机高速避障方案
  • 操作系统迁移至新 SSD 的两种实用方法
  • Rust 异步微服务架构最佳实践与常见反模式
  • 知网 AIGC 检测原理及降低 AI 疑似度策略
  • C++ 进阶:哈希表原理与实现
  • DeepSeek-R1 通过知识蒸馏将推理能力迁移至 Qwen 系列模型
  • 动态规划专题:01 背包模型详解与空间优化
  • Cursor 与 GitHub Copilot 深度对比:架构、性能与选型指南
  • 8 卡 RTX 5090 服务器 llama.cpp 部署与性能调优指南
  • Diffusion Transformer (DiT) 架构解析:从图像生成到机器人动作预测
  • Claude AI 注册流程解析与手机号验证解决方案
  • FASTLIVO2 算法解析与实战(一):SLAM 系统架构详解
  • Python 中的“==”与 is:本质区别与实战优化
  • Flutter 组件 upnp_client 的鸿蒙适配实战:跨设备发现与投屏控制
  • Git 局域网协作教程

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online