You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++98 TCP HTTP服务器recv/read无法正确接收二进制文件数据

C++ HTTP 1.1服务器recv/read接收二进制文件丢失字节问题

编写C++ HTTP 1.1服务器时,遇到recv/read无法正确接收数据的问题:接收二进制文件会丢失必要字节。浏览器网络面板显示数据完整,但recv/read读取不到缺失的部分。

实际接收内容:

M-IPNGM$
^Z$
IHDRHFM-tM-.M-FDsBITHHHH|HdM-HYtEXtSoftwaregnome-screenshotM-o^CM-?>tEXtCreation TimeSat 26 Oct 2024 07:34:33 PM CESTKuM-8M-:IDATHM-YcM-|M-?M-?M-??F$M-@M-DM-@F0^D$
DBM-FuV4ENDM-.B`M-^B

预期接收内容:

M-IPNGM$
^Z$
@@@MIHDR@@@D@@@CHF@@@M-4M-tM-.M-F@@@DsBITHHHH|HdM-H@@@YtEXtSoftware@gnome-screenshotM-oCM-?>@@@.tEXtCreation Time^@Sat 26 Oct 2024 07:34:33 PM CESTKuM-8M-:@@@UIDATHM-YcM-|M-?M-?M-??F$M-@M-DM-@F0D@M-B$
DBM-FuV4@@@@IENDM-.B`M-^B

相关代码(仅排查recv/read未读取全量字节的原因,勿提代码写法建议):

std::size_t len(char *str) {
    int i = 0;
    while (str[i++]);
    return i;
}

static char *add(char *buffer, char *to_add) {
    char *returning = (char *)malloc(len(buffer) + 3);
    int i = 0;
    while (buffer[i]) {
        returning[i] = buffer[i];
        i++; 
    }
    free(buffer);
    returning[i++] = to_add[0];
    returning[i++] = to_add[1];
    returning[i] = 0;
    return returning;
}

void Webserv::run(int socket) {
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    int response_content = 0;
    char buffer[2];
    int client_socket;
    char *buff;
    std::string request;

    std::cout << "Server is running and waiting for connections on port: " << port << std::endl;
    std::cout << "http://localhost:" << port << "/" << std::endl;

    while (true) {
        std::string boundary;
        int read_status = 1;
        bool loop = false;
        boundary.clear();
        client_socket = accept(socket, (struct sockaddr*)&client_addr, &client_len);
        if (client_socket < 0) {
            std::cerr << "Error accepting connection" << std::endl;
            continue;
        }

        // std::cout << "Connection accepted." << std::endl;
        memset(buffer, 0, sizeof(buffer));
        int temp = 0;
        std::cout << "A" << std::endl;
        buff = (char *)malloc(1);
        buff[0] = 0;
        while (read_status != 0 && read_status != -1) {
            read_status = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
            // std::cout << buffer << std::endl;
            buff = add(buff, buffer);
            request += std::string(buffer);
            if (!body(request, temp, loop, boundary))
                break;
            temp++;
        }
        std::cout << buff << std::endl;
        std::cout << "A" << std::endl;
        // std::cout << request << std::endl;

        if (read_status == 0 || read_status == -1)
            close(client_socket);

        rq = request;
        // std::cout << request << std::endl;
        request.clear();
        int status_code = get_status_code(rq);

        if (rq.get_method() == "GET")
            response_content = GET(status_code, client_socket);
        else if (rq.get_method() == "POST")
            response_content = POST(status_code, client_socket);
        else if (rq.get_method() == "DELETE")
            response_content = DELETE(status_code, client_socket);
        else
            show_page("text/html", "error_pages/406_error_page.html", 406);
        // std::cout << response_content << std::endl;
        // request.clear();
        close(client_socket);
    }
}

已尝试操作:

  • 调整char buffer[2]的大小,问题未改善
  • 使用char*或std::string接收均出现字符丢失,尚未尝试std::vector

内容的提问来源于stack exchange,提问作者Bionic Angel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:40:11