根据this solution通过TCP发送图像。由于代码与其他方式相比非常优雅,并且图像和文件都是数据,我相信我们可以使用几乎相同的代码发送文件。
因此,如果我想将文件从客户端发送到服务器。
在客户端端
将文件内容读入缓冲区
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);
}
发送缓冲区
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);
}
在服务器端
将东西收集到缓冲区中,其大小来自步骤1
fwrite(buf,sizeof(char),size,fs);
将缓冲区写入文件
{{1}}
此代码将编译并运行。
当我从客户端向服务器发送cpp二进制文件(24k)时,由于客户端和服务器都在同一台机器(OS X)上,因此将接收该二进制文件并可以执行。
但是如果服务器将文件转发回客户端,并且客户端多次将此文件转发回服务器,则该二进制文件将被破坏。但是发送的字节数和接收的字节数是相同的,文件大小仍然是24k。
我想知道这里出了什么问题。
这是操作系统错误吗?
谢谢,
答案 0 :(得分:2)
send()
和recv()
都不保证实际发送或接收所请求的字节数。在这种情况下,返回值仍然是正数,但小于系统调用中请求的字节数。
send()
和recv()
的手册页文档中详细记录了这一点。请重新阅读操作系统的文档以获取这些系统调用。
应用程序有责任再次尝试,发送或接收剩余的字节。
此代码假定发送的字节数是它请求发送的字节数。它看起来似乎正确处理recv()
的返回状态,但不是send()
。在发送的字节数较少之后,此代码仍假定发送或接收了整个内容,fwrite()
系统调用将最终写入垃圾而不是文件的后半部分。
答案 1 :(得分:-1)
如果客户端和服务器都在同一个文件夹中,那么在这种情况下就像复制和粘贴文件一样。
因此,当客户端发送文件时,它将
在服务器端,
因此,通过引起竞争条件,第2步会出现问题。