c++ - C 套接字文件传输损坏的数据

标签 c++ c sockets tcp

根据 this solution通过 TCP 发送图像。由于代码相比其他方式非常优雅,而且图像和文件都是数据,我相信我们可以使用几乎相同的代码发送一个文件。

所以如果我想从客户端向服务器发送文件。

客户端

  1. 获取文件大小
  2. 发送文件大小 //上面的步骤总是可行的,所以我只会在这里展示代码
  3. 将文件内容读入缓冲区

    char buf[size];
    read(fs,buf,size);
    
  4. 发送缓冲区

    int bytes = 0;
    for (uint i = 0;i<size;i+=bytes)
    {
        if ((bytes = send(sock,buf+i,size-i,0))<0)
        {
            fprintf(stderr,"Can not send file\n");
            close(fd);
            return false;
        }
        fprintf(stderr,"bytes write = %d\n",bytes);
    }
    

服务器

  1. 接收文件大小
  2. 将步骤 1 中的内容接收到缓冲区中

    char buf[size];
    int bytes=0;
    for (uint i = 0;i<size;i+=bytes)
    {
        if ((bytes = recv(sock,buf+i,size-i,0))<0)
        {
            fprintf(stderr,"Can not receive file\n");
            return false;
        }
        fprintf(stderr,"bytes read = %d\n",bytes);
    }
    
  3. 将缓冲区写入文件

    fwrite(buf,sizeof(char),size,fs);
    

此代码将编译并运行。

当我从客户端向服务器发送一个 cpp 二进制文件 (24k) 时,由于客户端和服务器都在同一台机器 (OS X) 上,因此该二进制文件将被接收并可以执行。

但如果服务器将文件转发回客户端,客户端多次将此文件转发回服务器,则此二进制文件将被损坏。但是发送的字节数和接收的字节数是一样的,文件大小还是24k。

我想知道这里出了什么问题。

这是操作系统错误吗?

谢谢,

最佳答案

send()recv() 都不能保证实际发送或接收请求的字节数。在这种情况下,返回值仍将为正,但小于系统调用中请求的字节数。

这在 send()recv() 的手册页文档中有详细记录。请重新阅读您的操作系统文档以了解这些系统调用。

再次尝试发送或接收剩余字节是应用程序的责任。

此代码假定发送的字节数是它请求发送的字节数。它似乎确实可以正确处理 recv() 的返回状态,但不能正确处理 send() 的返回状态。在发送了更少的字节后,这段代码仍然假设所有的内容都被发送或接收,并且 fwrite() 系统调用最终将写入垃圾而不是文件的后半部分。

关于c++ - C 套接字文件传输损坏的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36538993/

相关文章:

c - 在c中将大字符数组作为输入

c - 如何将字符数组中的内容写入文本文件?

c++ - 配对 socket

c - 如何使用 getaddrinfo 连接到使用外部 IP 的服务器?

c++ - recv() 没有收到预期的字节数

c++ - 构造函数的参数数量

c++ - 如何在安装了 WSL 的 Visual Studio Code 中修复 "g++: error: helloworld.cpp: No such file or directory"?

c++ - VS2010 : Setting Up File Details on Application Build

c++ - 如何在编译时计算类成员的偏移量?

c - 动态改变 Material 的颜色