0

我有一个任务,我必须从服务器下载一个文件..但我有这个东西,有时数据被发送,有时他们只是没有!

服务器 :

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);
4

2 回答 2

1

由于实现原因(套接字、TCP 堆栈、以太网堆栈……),即使发送了这么多字节,每次读取也可能不会总是得到 1024 个字节。

if (n < 1024)用来检查你是否完成了。这不应该用套接字来完成。

首先,您需要更改readrecv专门设计用于使用套接字的哪个。如果服务器已按顺序关闭连接并且发生错误,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);
于 2013-10-28T15:10:49.893 回答
0

客户端接收到的数据可能少于 1024,但这不是发送的最后一个数据块。这可能是由于链路通道的状况造成的。您的代码没有考虑这种情况,好像从套接字读取的数据小于 1024,while 由 break 指令终止。结果,剩余的数据(正确发送)在客户端丢失。

为了改进您的文件传输系统,我建议将文件的大小作为第一信息发送,然后使用文件大小来验证文件何时完全接收。

另一种选择是使用sendfile系统调用,它针对这种操作进行了优化。

于 2013-10-28T14:59:26.103 回答