C语言Socket传输文件异常:客户端仅生成空文件无数据
问题排查:C语言文件传输客户端无数据写入的问题
我帮你梳理了代码里的问题,核心错误确实出在你标注的判断语句上,还有几个容易忽略的字节序问题,咱们一步步解决:
1. 最直接的错误:read_all返回值判断逻辑完全错误
你的read_all函数设计是成功读取指定的len字节后,返回读取的总字节数(也就是传入的len值),但你在客户端RecvFile里写了:
if(read_all(clientSocket, &size, sizeof(size)) == 1)
这就导致哪怕成功读取了文件大小,这个条件也永远不成立,后面接收文件内容的循环根本没执行,所以你的.txt文件才会是空的。
修改方案:
把判断条件改成检查是否读取到了完整的sizeof(size)字节:
// 检查是否成功读取了完整的文件大小字段 if(read_all(clientSocket, &size, sizeof(size)) == sizeof(size))
2. 字节序转换的双向错误
你在服务器和客户端的字节序处理完全搞反了,这会导致文件大小解析错误(哪怕修复了前面的判断,也可能因为大小不对导致接收异常):
- 服务器端:你用了
ntohl(size),但ntohl是把网络字节序转为主机字节序,服务器应该做的是把主机字节序的文件大小转成网络字节序,因为off_t是64位类型,应该用htonll(32位系统用htonl) - 客户端:你用了
ntohl(size),同样,64位的数值应该用ntohll来转为主机字节序
修改服务器端代码:
off_t size = s.st_size; // 错误:ntohl是客户端做的转换,服务器要转成网络字节序 // off_t tmp_size = ntohl(size); // 正确:将主机字节序的64位大小转为网络字节序 off_t tmp_size = htonll(size);
修改客户端代码:
// 正确:将网络字节序的64位大小转为主机字节序 size = ntohll(size);
3. 额外的小提醒
- 如果你的系统不支持
htonll和ntohll,可以自己实现64位的字节序转换函数 - 可以在服务器发送大小后,打印
tmp_size的日志;客户端接收后打印解析后的size,验证大小是否正确匹配
把这些修改完后,再测试应该就能正常传输文件内容了。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

