C语言HTTP服务器返回图片时出现net::ERR_CONTENT_LENGTH_MISMATCH 200错误
解决HTTP服务器图片请求的
net::ERR_CONTENT_LENGTH_MISMATCH错误 问题根源
你的代码能正常处理HTML/CSS但无法加载图片,核心问题出在二进制数据与字符串操作的不兼容:
- 图片属于二进制文件,内容中大概率包含
\0字节(字符串结束符),但你用strcat拼接响应体时,strcat会在遇到第一个\0时停止拼接,导致实际发送的图片数据长度远小于Content-Length声明的数值,触发浏览器的长度不匹配错误。 - 同时存在两个潜在隐患:
bzero(response, sizeof(response)):response是指针,sizeof(response)仅能获取指针本身的大小(通常为4/8字节),而非你malloc的50000字节,导致响应头后的内存可能残留垃圾数据。- 固定malloc 50000字节:若图片大小超过该值,会触发内存溢出,破坏响应数据结构。
修复步骤
- 替换字符串拼接为内存拷贝:处理二进制内容时,用
memcpy替代strcat/strcpy,避免被\0截断。 - 动态计算响应总长度:先计算响应头的长度,加上文件大小后再malloc对应内存,避免溢出。
- 正确初始化内存:用
memset清零整个响应缓冲区,而非仅清理指针大小的内存。 - 发送完整响应长度:确保
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
相关产品推荐
相关产品推荐

