使用strncpy复制TCP流是否引发代理服务器图片转发故障?
问题分析与解决方案
嘿,这个问题我之前踩过一模一样的坑!核心问题出在你用了strncpy来处理图片这类二进制数据——这函数从设计上就不是干这个活的!
为什么会出现这种差异?
- Case 1能正常工作的原因:它直接把
read读取到的字节原封不动通过write转发,完全不关心数据内容是文本还是二进制,所有字节都能完整传输,自然图片和HTML都没问题。 - Case 2处理HTML正常但图片失败的原因:HTML是纯文本格式,有效内容里不会包含
\0(空字节),strncpy可以完整复制所有内容;但图片是二进制数据,里面大概率会存在\0字节,而strncpy的逻辑是遇到\0就停止复制,这就导致cachebuf里的图片数据被截断,浏览器收到残缺的二进制流自然无法解析显示。
修复方案:用memcpy替代strncpy
memcpy是专门用来按字节数复制数据的函数,它完全不关心数据里有没有\0,只会严格按照你指定的字节数完成复制。修正后的代码如下:
// 初始化cachebuf和size char* cachebuf = NULL; size_t size = 0; int con; do { memset(buffer, 0, BUFSIZE); con = read(sockfd, buffer, BUFSIZE); // 处理read错误或者EOF的情况 if (con <= 0) { break; } size += con; // 用临时指针接收realloc结果,避免分配失败时丢失原指针 char* temp_buf = (char*)realloc(cachebuf, size); if (!temp_buf) { // 内存分配失败,释放已分配内存防止泄漏 free(cachebuf); cachebuf = NULL; // 可根据需求添加错误处理逻辑,比如关闭连接 break; } cachebuf = temp_buf; // 用memcpy替代strncpy,按字节数复制 memcpy(cachebuf + (size - con), buffer, con); } while(con > 0); if (cachebuf != NULL && size > 0) { write(client, cachebuf, size); free(cachebuf); // 别忘了释放内存,避免泄漏 }
额外注意事项
- 必须处理
read返回-1的错误情况,否则可能陷入死循环或错误累加。 realloc可能返回NULL(内存分配失败),一定要检查返回值,避免野指针问题。- 最终务必释放
cachebuf,防止内存泄漏。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

