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

C语言Socket读取HTTP响应时图片文件读取异常问题排查

问题原因

核心问题有2个:

  • 内存扩容逻辑计算错误:当前代码判定缓冲区满后,先将available_buf_size翻倍,再调用realloc时错误的传入了available_buf_size + tot_read作为新缓冲区大小,导致实际分配的缓冲区大小和记录的available_buf_size不匹配,后续读取的写入位置计算会出现偏差。
  • 二进制数据长度判断错误:函数仅返回缓冲区指针,没有同步返回实际读取的总字节数tot_read。文本类HTTP响应没有空字节(\0),你写入文件时用strlen计算长度可以得到正确值;但图片是二进制数据,内容中会存在大量\0,strlen碰到第一个\0就会停止计数,导致实际写入文件的字节数远小于真实读取的字节数,最终图片无法打开。你调试时看到缓冲区内容只有379个字符,也是因为调试器按字符串规则解析,碰到非文本字节就截断显示,实际数据已经完整存在缓冲区中。
修复方案

1. 修正内存扩容逻辑

删除realloc参数中多余的tot_read相加逻辑,保证实际分配的缓冲区大小和available_buf_size记录的数值一致,同时去掉无意义的空缓冲区memset操作。

2. 新增总读取字节数输出

修改函数定义,通过输出参数返回实际读取的总字节数,写入文件时直接用这个值作为写入长度,不要使用任何字符串相关的长度计算函数。

修复后代码示例

// 新增参数tot_out,用于输出实际读取的总字节数
unsigned char *read_unknown_size(int fd, ssize_t *tot_out) {
    int available_buf_size = 1000, tot_read = 0, curr_read_size;
    unsigned char *buf = calloc(available_buf_size, 1), *tmp_ptr;
    if (!buf) {
        fprintf(stderr,"calloc failed\n");
        exit(EXIT_FAILURE);
    }
    while ((curr_read_size = (int) read(fd, buf + tot_read, available_buf_size - tot_read)) != 0) {
        if (curr_read_size == -1) {
            perror("failed to read\n");
            free(buf);
            exit(EXIT_FAILURE);
        }
        tot_read += curr_read_size;
        if (tot_read >= available_buf_size) { //缓冲区已满,扩容
            available_buf_size *= 2;
            // 修正realloc大小计算
            tmp_ptr = realloc(buf, available_buf_size);
            if (!tmp_ptr) {
                fprintf(stderr,"realloc failed\n");
                free(buf);
                exit(EXIT_FAILURE);
            }
            buf = tmp_ptr;
        }
    }
    *tot_out = tot_read;
    return buf;
}

调用示例

ssize_t read_len;
unsigned char *resp = read_unknown_size(fd, &read_len);
// 写入文件时用read_len作为长度参数,不要用strlen(resp)
fwrite(resp, 1, read_len, fp);
额外注意事项

当前实现依赖服务端返回Connection: close头才会终止读取,如果后续需要适配长连接场景,建议先解析HTTP响应头的Content-Length字段,按指定长度读取响应体,避免出现读取超时或多读的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:15:06