使用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
相关产品推荐
相关产品推荐

