羽生景宇 2025-01-29 23:20 采纳率: 100%
浏览 9
已结题

求解!tcp传输文件开头多了一个空格!

我是初学者,尝试tcp传输文件时遇到问题:传输一个文本文件内容为”1111hello word!“,接收端接收后前面多了一个空格” 1111hello word!“
问题是发送端读取的内容十六进制打印出来没有问题,接收端接收到的数据打印出来也没有问题,但写入之后的文本就是多了一个空格!
我的发送端代码:


void send_file(SOCKET sock, const char* filepath) {
    FILE* file = fopen(filepath, "rb");
    if (!file) {
        printf("无法打开文件: %s\n", filepath);
        return;
    }
#define BUFFER_SIZE 1024
    char buffer[BUFFER_SIZE];
    int bytesRead;

    while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, file)) > 0) {
        printHex(buffer);//调试
        int bytesSent = send(sock, buffer, bytesRead, 0);
        if (bytesSent == SOCKET_ERROR) {
            printf("发送失败!\n");
            break;
        }
        memset(buffer, 0, BUFFER_SIZE);
    }
    // 发送EOF标志,表示文件传输结束
    const char* eofMessage = "EOF";  // EOF标志
    int eofMessageLength = strlen(eofMessage) + 1;  // +1包含结尾的'\0'字符
    int bytesSent = send(sock, eofMessage, eofMessageLength, 0);
    if (bytesSent == SOCKET_ERROR) {
        printf("发送EOF失败!\n");
    }
    else {
        printMsg("EOF已发送,文件传输结束。\n", 0);
    }

    fclose(file);
}

接收端代码:

void receive_file(SOCKET clientSock, const char* buff) {
    char savePath[512] = "C:\\desktop\\sd\\";  // 增加路径长度
    char filename[256];
    get_filename_from_path(buff, filename);

    // 使用 snprintf 安全拼接路径
    snprintf(savePath + strlen(savePath), sizeof(savePath) - strlen(savePath), "%s", filename);

    FILE* file = fopen(savePath, "wb");
    if (!file) {
        printf("无法创建文件: %s\n", savePath);
        return;
    }

#define BUFFER_SIZE 1024
    char buffer[BUFFER_SIZE];
    int bytesReceived;

    while (1) {
        bytesReceived = recv(clientSock, buffer, BUFFER_SIZE, 0);
        printHex(buffer);  // 调试

        if (bytesReceived > 0) {
            // 如果收到"EOF"标志,结束文件传输
            if (!memcmp(buffer, "EOF", 3)) {
                printf("接收到EOF标志,文件传输结束。\n");
                break;  // 跳出循环,停止接收文件
            }

            // 如果接收到的数据不是EOF,写入文件
            fwrite(buffer, 1, bytesReceived, file);

            // 清空缓冲区(确保不会重复接收相同数据)
            memset(buffer, 0, BUFFER_SIZE);
        }
        else if (bytesReceived == 0) {
            // 如果连接关闭,跳出循环
            printf("文件接收完成。\n");
            break;  // 跳出循环
        }
        else if (bytesReceived == SOCKET_ERROR) {
            printf("接收失败!\n");
            break;  // 出错,退出接收过程
        }
    }


    // 在文件传输完成后关闭文件
    fclose(file);
    printf("文件已关闭。\n");
}

已经困扰我很久了,问了AI也是无济于事,真心求解!感谢各位!

  • 写回答

4条回答 默认 最新

  • 羽生景宇 2025-02-03 17:36
    关注

    询问deep seek反复后解决。
    顺带一说,deep seek比免费版chatgpt好太多!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    🔧 问题根源
    客户端的命令/sd C:\desktop\wwa.txt和文件内容111111hello world!被合并发送,服务端在接收时一次性读取了整个缓冲区,导致文件开头包含命令残留数据。

    📝 总结
    通过分离命令与文件传输阶段,并确保缓冲区完全清空,可有效解决文件开头多出空格的问题。此方案强调同步协议设计和缓冲区管理,适用于类似基于TCP的流式数据传输场景。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月11日
  • 已采纳回答 2月3日
  • 创建了问题 1月29日