根据 this solution通过 TCP 发送图像。由于代码相比其他方式非常优雅,而且图像和文件都是数据,我相信我们可以使用几乎相同的代码发送一个文件。
所以如果我想从客户端向服务器发送文件。
在客户端
- 获取文件大小
- 发送文件大小 //上面的步骤总是可行的,所以我只会在这里展示代码
将文件内容读入缓冲区
char buf[size]; read(fs,buf,size);
发送缓冲区
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 中的内容接收到缓冲区中
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); }
将缓冲区写入文件
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/