Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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_Linux_File_Fwrite_Transfer - Fatal编程技术网

文件传输成功,但获胜';在C中循环时不能退出

文件传输成功,但获胜';在C中循环时不能退出,c,linux,file,fwrite,transfer,C,Linux,File,Fwrite,Transfer,编辑:将while循环条件从>0更改为=0。打印内容后,终端上还会输出2行或更多的换行符,但文件中没有 我正在做一个从客户端到服务器的文件传输。内容传输成功,但接收时不会退出while循环。我的while状态有什么问题吗?在我强制停止程序后,我可以看到文件实际上已经成功复制,在将所有内容写入文件后,它不会退出while循环 这是我遇到问题的代码: ssize_t bytes_read = 0; int error; while((bytes_read = read(sd, buf, sizeo

编辑:将while循环条件从
>0
更改为
=0
。打印内容后,终端上还会输出2行或更多的换行符,但文件中没有

我正在做一个从客户端到服务器的文件传输。内容传输成功,但接收时不会退出while循环。我的while状态有什么问题吗?在我强制停止程序后,我可以看到文件实际上已经成功复制,在将所有内容写入文件后,它不会退出while循环

这是我遇到问题的代码:

ssize_t bytes_read = 0;
int error;

while((bytes_read = read(sd, buf, sizeof(buf))) != 0){ 
                        
                        printf("writing: %s\n", buf);
                        if((error = fwrite(buf, 1, bytes_read, fp)) < 0)
                        {
                            printf("error");
                        }
                        if((bytes_read = read(sd, buf, sizeof(buf))) < 0){
                            break;
                        }
                            
}
ssize\u t bytes\u read=0;
整数误差;
而((bytes_read=read(sd,buf,sizeof(buf)))!=0{
printf(“写入:%s\n”,buf);
if((error=fwrite(buf,1,bytes\u read,fp))<0)
{
printf(“错误”);
}
if((bytes_read=read(sd,buf,sizeof(buf)))<0){
打破
}
}
尽量把它控制在最低限度,因为我确信这里有一些非常简单的错误

编辑:我尝试了一个更大的文件,它似乎缺少一些内容在这里和那里,但不是在一个一致的模式

编辑:这是客户端

else if(strcmp(shortCommand, "put") == 0){
            
            char *tmp = buf + 4;
            char filename[MAX_BLOCK_SIZE];
            strcpy(filename, "filename ");
            strcat(filename, tmp);
            FILE *fp;
            printf("File name: %s\n", tmp);
            fp = fopen(tmp, "rb");
            if(fp == NULL){
                
                printf("ERROR: Requested file does not exist.\n");
                
            }
            else{
            printf("Client sending filename...\n");
            if ((nw = write(sd, buf, sizeof(buf))) < 0){            //sending the file name to the client first
                printf("Error sending client's filename.\n");
            }
            
            printf("Client sending file...\n");
            size_t bytes_read = 0;
            ssize_t bytes_written = 0;
            
            
            while((bytes_read = fread(buf, 1, sizeof(buf), fp)) != 0){ //sending the file contents
            
                if ((bytes_written = write(sd, buf, bytes_read)) < 0){
                    printf("Error sending client file.\n");
                }
            
            }
            
            fclose(fp);
            }   
    }
else if(strcmp(shortCommand,“put”)==0){
char*tmp=buf+4;
字符文件名[最大块大小];
strcpy(文件名,“文件名”);
strcat(文件名,tmp);
文件*fp;
printf(“文件名:%s\n”,tmp);
fp=fopen(tmp,“rb”);
如果(fp==NULL){
printf(“错误:请求的文件不存在。\n”);
}
否则{
printf(“客户端发送文件名…\n”);
如果((nw=write(sd,buf,sizeof(buf)))<0{//首先将文件名发送到客户端
printf(“发送客户端文件名时出错。\n”);
}
printf(“客户端发送文件…\n”);
大小\u t字节\u读取=0;
ssize_t bytes_write=0;
而((bytes_read=fread(buf,1,sizeof(buf,fp))!=0){//发送文件内容
如果((字节写入=写入(sd、buf、字节读取))<0){
printf(“发送客户端文件时出错。\n”);
}
}
fclose(fp);
}   
}

服务器代码假定它将在读取客户端传输的所有数据后观察
read()
返回0,但这不会仅仅因为客户端停止发送数据而发生
read()
返回0,表示已到达文件的结尾,但在这种意义上,“file”表示其套接字的读取端。在客户端关闭对等套接字之前,服务器不会在其套接字上感知EOF。这是完全合理的,因为在此之前,客户机可能会发送更多数据,证明之前确实没有达到EOF。因此,如果服务器在接收到所有数据后尝试在套接字上执行(阻塞)读取,那么它将阻塞,直到客户端发送更多数据或关闭连接,或者直到检测到错误、被信号中断等

如果客户机实际上不打算在文件内容之后发送任何进一步的数据,那么它应该在发送文件内容的所有字节后,或者至少在写入端,关闭()该套接字

另一方面,如果客户端保持套接字打开,因为它打算稍后发送更多数据,那么您需要一个新策略。在这种情况下,文件内容的结尾与流的逻辑结尾不一致,因此需要一种不同的机制来与保存文件结尾数据的服务器通信。这就是HTTP等通信协议的用武之地,但出于您的目的,您不需要像HTTP这样复杂的协议


例如,客户机可以将数据作为一个或多个块发送到服务器,每个块包含一个字节计数,后跟指定数量的内容字节数。您可以坚持将整个文件内容始终放在一个块中,但如果您希望允许将文件拆分为多个块,则可以使用块长度为零的方式来表示数据的结束。

传输是否真的成功?2ne
read
读取的内容将被丢弃:EOF由返回值
0
表示,因此您应该检查它。我只是用一个较大的文件尝试了它,在我强制停止退出while循环后,它只显示传输的部分内容,而不是整个文档。可能是因为我的while循环没有正确结束,或者是其他原因?发送者在发送内容后会做什么?它是否关闭流?
!=如果
read()
返回错误,0将导致无休止的循环。所以原来的版本更好。您仍然没有解释循环中第二个
read()
被丢弃的原因。