C语言Socket文件收发问题:客户端仅接收首行如何修复?
问题解决:Socket传输TXT文件仅接收第一行的修复方案
问题根源
- 客户端仅执行一次
recv,只能获取服务器首次发送的一行数据,后续服务器发送的内容未被接收 - 服务器固定发送
T_MAX字节(而非实际读取的有效数据长度),可能导致冗余数据干扰 - 服务器用
!feof(Log)作为循环条件,存在逻辑缺陷,会触发最后一次无效发送
修复后的服务器代码
FILE *Log = fopen("Log.txt", "r"); if (!Log) { printf("[SERVER] 打开文件失败\n"); return 1; } char ms[T_MAX]; // 用fgets返回值判断读取是否成功,替代feof的错误逻辑 while (fgets(ms, T_MAX, Log) != NULL) { // 发送实际读取的有效数据长度,而非固定T_MAX字节 size_t send_len = strlen(ms); if (send(client_socket, ms, send_len, 0) < 0) { printf("[SERVER] ERROR -> %d\n", WSAGetLastError()); closesocket(servidor_socket); closesocket(client_socket); fclose(Log); WSACleanup(); return 1; } } fclose(Log);
服务器修改说明
- 用
fgets(...) != NULL作为循环终止条件:fgets读取到文件末尾或失败时返回NULL,是判断文件读取完成的正确方式 - 发送
strlen(ms)长度的数据:避免发送缓冲区中未使用的空字符,减少冗余传输 - 增加文件打开失败的判断,提升代码鲁棒性
修复后的客户端代码
char ms[T_MAX]; int recv_len; // 循环接收直到服务器关闭连接或出现错误 while ((recv_len = recv(socket_aplication, ms, T_MAX - 1, 0)) > 0) { ms[recv_len] = '\0'; // 手动添加字符串终止符,避免printf输出乱码 printf("%s", ms); } // 处理接收错误的情况 if (recv_len < 0) { printf(" ERROR -> %d\n", WSAGetLastError()); closesocket(socket_aplication); WSACleanup(); return 1; }
客户端修改说明
- 循环调用
recv:TCP是流式协议,服务器多次发送的数据可能被合并或拆分,必须循环接收直到连接关闭(recv返回0) - 手动添加
'\0':recv不会自动添加字符串结束符,直接printf会读取缓冲区外的垃圾数据 - 缓冲区预留1字节给终止符:
recv长度设为T_MAX - 1,避免缓冲区溢出
额外注意事项
如果传输大文件,建议先发送文件总长度,客户端先接收长度再接收对应字节数,这种方式比依赖连接关闭更可靠。
内容的提问来源于stack exchange,提问作者Ponce Francoo
相关产品推荐
相关产品推荐

