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

使用C语言fread和send通过TCP Socket发送HTTP响应时图片渲染出错

C语言简易Web服务器图片加载错误问题及修复

问题描述

我用C语言开发了一个简易Web服务器作为个人项目,它支持接收静态文件路径并提供静态文件服务。目前所有text/*类型的内容都能正常加载,但浏览器始终提示图片加载错误。Firefox v112.0的网络标签页显示图片请求状态为200 OK,但图片无法正常渲染。

已确认:

  • 图片本身未损坏
  • 已发送必要的HTTP头部,Content-Type设置正确
  • 多款浏览器测试均出现相同问题

原代码问题片段

负责发送静态文件的代码片段(存在问题的部分):

// send the file in chunks
char file_buffer[BUFF_SIZE];
size_t bytes_read = 0;
while (bytes_read < fsize)
{
    size_t bytes_to_read = fsize - bytes_read;
    if (bytes_to_read > BUFF_SIZE)
        bytes_to_read = BUFF_SIZE;

    size_t result = fread(file_buffer, 1, bytes_to_read, fp);
    if (result == 0)
        break;

    if (send(client_server->conn_fd, file_buffer, result, 0) < 0)
    {
        fclose(fp);
        err_n_die("Error while sending");
    }

    bytes_read += result;
}

fclose(fp);

问题原因

send函数并非总能一次性发送请求的全部字节,它的返回值是实际成功发送的字节数。原代码假设每次send都会发送完整的result字节,但在实际网络环境中,尤其是处理二进制图片这类数据时,很可能出现部分发送的情况,导致图片数据不完整,浏览器无法正确解析。

修复后的代码

// send file in chunks
char file_buffer[BUFF_SIZE];
size_t bytes_read = 0;
while (bytes_read < fsize)
{
    size_t bytes_to_read = fsize - bytes_read;
    if (bytes_to_read > BUFF_SIZE)
        bytes_to_read = BUFF_SIZE;

    size_t result = fread(file_buffer, 1, bytes_to_read, fp);
    if (result == 0)
        break;

    size_t bytes_sent = 0;
    while (bytes_sent < result)
    {
        ssize_t sent = send(client_server->conn_fd, file_buffer + bytes_sent, result - bytes_sent, 0);
        if (sent == -1)
        {
            fclose(fp);
            err_n_die("Error while sending");
        }
        bytes_sent += sent;
    }

    bytes_read += result;
}

fclose(fp);

修复说明

修复后的代码增加了内层循环:每次调用send后,根据实际发送的字节数更新bytes_sent,直到当前读取的文件片段全部发送完成,确保图片的二进制数据完整传输到浏览器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:42:49