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

C语言HTTP服务器返回图片时出现net::ERR_CONTENT_LENGTH_MISMATCH 200错误

解决HTTP服务器图片请求的net::ERR_CONTENT_LENGTH_MISMATCH错误

问题根源

你的代码能正常处理HTML/CSS但无法加载图片,核心问题出在二进制数据与字符串操作的不兼容:

  • 图片属于二进制文件,内容中大概率包含\0字节(字符串结束符),但你用strcat拼接响应体时,strcat会在遇到第一个\0时停止拼接,导致实际发送的图片数据长度远小于Content-Length声明的数值,触发浏览器的长度不匹配错误。
  • 同时存在两个潜在隐患:
    1. bzero(response, sizeof(response)):response是指针,sizeof(response)仅能获取指针本身的大小(通常为4/8字节),而非你malloc的50000字节,导致响应头后的内存可能残留垃圾数据。
    2. 固定malloc 50000字节:若图片大小超过该值,会触发内存溢出,破坏响应数据结构。

修复步骤

  1. 替换字符串拼接为内存拷贝:处理二进制内容时,用memcpy替代strcat/strcpy,避免被\0截断。
  2. 动态计算响应总长度:先计算响应头的长度,加上文件大小后再malloc对应内存,避免溢出。
  3. 正确初始化内存:用memset清零整个响应缓冲区,而非仅清理指针大小的内存。
  4. 发送完整响应长度:确保send_response发送的是响应总长度(头+体),而非用strlen计算(strlen同样会被\0截断)。

修正后的代码示例

读取文件部分(保留逻辑,补充内存释放)

FILE* file = fopen(full_fpath, "rb");
if (file == NULL) {
    char* response = build_response("404", NULL, NULL, 0, now);
    send_response(sd, response);
    free(response); // 释放内存避免泄漏
    return NULL;
}
fseek(file, 0L, SEEK_END);
long int file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
unsigned char* file_content = (unsigned char*)malloc(file_size * sizeof(unsigned char));
size_t bytes_read = fread(file_content, sizeof(unsigned char), file_size, file);
printf("%zu\n", bytes_read);
fclose(file);

// 构建响应时需传递总长度,这里可修改build_response返回结构体或额外参数
char* response;
size_t total_len;
build_response("200", f_type, (char*)file_content, bytes_read, now, &response, &total_len);
send_response(sd, response, total_len);
free(file_content);
free(response);

构建响应部分(核心修改)

// 假设你定义的常量如下
#define OK_RESPONSE "HTTP/1.1 200 OK\r\n"
#define TYPE "Content-Type: "
#define LEN "Content-Length: "

void build_response(char* status, char* type, char* file, size_t file_size, struct tm* now, char** out_response, size_t* out_total_len) {
    if(strcmp(status, "404") == 0) {
        char* not_found = "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<h1>404 Not Found</h1>";
        *out_total_len = strlen(not_found);
        *out_response = malloc(*out_total_len + 1);
        strcpy(*out_response, not_found);
        return;
    }

    // 计算响应头长度
    char length_str[50];
    sprintf(length_str, "%zu", file_size);
    size_t header_len = strlen(OK_RESPONSE) + strlen(TYPE) + strlen(type) + strlen("\r\n")
                      + strlen(LEN) + strlen(length_str) + strlen("\r\n\r\n");
    
    // 计算响应总长度
    *out_total_len = header_len + file_size;
    *out_response = malloc(*out_total_len);
    if (!*out_response) return;

    // 拼接响应头
    size_t pos = 0;
    strcpy(*out_response + pos, OK_RESPONSE);
    pos += strlen(OK_RESPONSE);
    
    strcpy(*out_response + pos, TYPE);
    pos += strlen(TYPE);
    
    strcpy(*out_response + pos, type);
    pos += strlen(type);
    
    strcpy(*out_response + pos, "\r\n");
    pos += strlen("\r\n");
    
    strcpy(*out_response + pos, LEN);
    pos += strlen(LEN);
    
    strcpy(*out_response + pos, length_str);
    pos += strlen(length_str);
    
    strcpy(*out_response + pos, "\r\n\r\n");
    pos += strlen("\r\n\r\n");
    
    // 用memcpy复制二进制内容,不受\0影响
    memcpy(*out_response + pos, file, file_size);
}

发送响应部分(按总长度发送)

void send_response(int sd, char* response, size_t total_len) {
    send(sd, response, total_len, 0);
}

额外注意事项

  • 内存管理:所有malloc分配的内存必须对应free,避免内存泄漏。
  • 错误检查:添加malloc、fopen、fread等操作的错误判断,提升代码健壮性。
  • 大文件适配:若需支持大尺寸图片,建议分块读取和发送,避免一次性申请过大内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 20:37:48