我有一项任务,我必须从服务器下载一个文件..但我有这个东西,有时数据发送,有时他们只是没有!!
服务器:
printf("Reading and sending the File.\n");
memset(buff, 0, sizeof(buff));
while((n=read(fp, buff, 1024)) > 0 )
{
printf ("%s \n", buff); //no problem, coz it reads the file correctly
write(connfd, buff, n);
memset(buff, 0, sizeof(buff));
}
客户端:
printf("Start downloading the file.\n");
bzero(&data,sizeof(data));
n = 0;
while (1)
{
n = read(sockfd , data, 1024);
if (n > 0)
{
data[n] = 0;
r = write (fp, data, n);
if (r < 0)
{
printf("Write to file !!!!!!\n");
exit(1);
}
}
printf ("\n%s\n", data);
bzero (&data, sizeof (data));
if (n < 1024)
break;
}
printf("Done downloading the file\n");
close (fp);
答案 0 :(得分:1)
由于实现原因(套接字,TCP堆栈,以太网堆栈......),即使发送了这么多内容,每次读取也不会总是得到1024个字节。
您正在使用if (n < 1024)
检查是否已完成。这不应该使用套接字来完成。
首先,您需要将read
更改为专门设计用于套接字的recv
。如果服务器已按顺序关闭连接,则recv
将返回0
,如果发生错误,则-1
将返回printf("Start downloading the file.\n");
ssize_t n;
while (1)
{
n = recv(sockfd, data, sizeof(data), 0);
if (n > 0)
{
r = write (fp, data, n);
if (r < 0)
{
perror("write");
exit(1);
}
printf ("\n%*s\n", n, data);
}
else if (!n)
break; // orderly shutdown
else {
perror("recv");
exit(1);
}
}
printf("Done downloading the file\n");
close (fp);
。任何其他返回值意味着:继续阅读!
{{1}}
答案 1 :(得分:0)
客户端可能接收的数据少于1024,但这不是最后发送的数据块。这可能是由链路信道的条件引起的。您的代码没有考虑这种情况,就好像从套接字读取的数据小于1024,while由break指令终止。结果,剩余数据(正确发送)在客户端丢失。
为了改善文件传输系统,我建议将文件大小作为第一个信息发送,然后使用文件大小来验证文件何时完全接收。
另一种选择可能是使用sendfile系统调用,该调用针对此类操作进行了优化。