从套接字意外行为读/写

时间:2013-10-28 14:51:13

标签: c sockets

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

服务器:

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

2 个答案:

答案 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系统调用,该调用针对此类操作进行了优化。