Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从套接字读/写异常行为_C_Sockets - Fatal编程技术网

C 从套接字读/写异常行为

C 从套接字读/写异常行为,c,sockets,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

我有一个任务,我必须从服务器下载一个文件。。但我有这样一件事,有时数据是发送的,有时他们只是不

服务器:

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);
printf(“开始下载文件。\n”);
bzero(&data,sizeof(data));
n=0;
而(1)
{
n=读取(sockfd,数据,1024);
如果(n>0)
{
数据[n]=0;
r=写入(fp,数据,n);
if(r<0)
{
printf(“写入文件!!!!!!!\n”);
出口(1);
}
}
printf(“\n%s\n”,数据);
bzero(&data,sizeof(data));
如果(n<1024)
打破
}
printf(“下载文件完成\n”);
关闭(fp);

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

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


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

由于实现原因(套接字、TCP堆栈、以太网堆栈等),即使发送了这么多字节,每次读取也可能无法始终获得1024字节

您正在使用
if(n<1024)
检查是否完成。这不应该用套接字来完成

首先,您需要将
read
更改为
recv
,这是专门为使用套接字而设计的<如果服务器已有序关闭连接,则code>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);
printf(“开始下载文件。\n”);
(三);
而(1)
{
n=recv(sockfd,data,sizeof(data),0);
如果(n>0)
{
r=写入(fp,数据,n);
if(r<0)
{
佩罗(“书面”);
出口(1);
}
printf(“\n%*s\n”,n,数据);
}
else如果(!n)
中断;//有序关机
否则{
perror(“recv”);
出口(1);
}
}
printf(“下载文件完成\n”);
关闭(fp);

printf(“%s\n”,浅黄色)应导致未定义的行为,因为read不提供以nul结尾的字符串。您正在使用
%s
。因此,您的代码在服务器端为小于1024字节的小文件工作的可能性在使用后是否关闭连接?@Bogdan是的我关闭了它您是否尝试使用fflush()刷新该文件?@GrijeshChauhan即使我将其删除,问题仍然存在!!我只是第一次和第二次尝试它发送第三次它没有!!!但在检查数据是否小于1024并中断循环之前,我会将其写入文件!!如果(n<1024)不是验证整个文件何时已完全发送的正确条件。我要做的事情是一次发送1024字节,因此当此条件为真时,意味着我到达文件的末尾!是的,你能做到。但是不能保证您将以1024字节的块接收它们。如果服务器没有显式调用
close
shutdown
,则检查<1024或零之间没有区别。