在C中成功发送和接收文件大小

Posted

技术标签:

【中文标题】在C中成功发送和接收文件大小【英文标题】:Sending and receiving file size successfully in C 【发布时间】:2020-11-03 05:58:10 【问题描述】:

我希望能够将文件从客户端发送到服务器。我正在使用 TCP。我正在尝试使用 fseek 等来获取文件的大小,因为我希望能够处理大文件,然后将这些字节的数据以及文件内容发送到服务器。到目前为止,根据我的 printf 消息,一切都通过并创建了文件。但是,在服务器上创建的文件是空的。我通过参数或其他方式发送和接收它的方式显然有问题,但我无法弄清楚。谁能告诉我哪里出了问题以及如何解决它,因为我很接近!

服务器部分:

if(getFile)
         
                char *tmp = buf + 9;
                char filename2[MAX_BLOCK_SIZE];
                int length, x;
                long file_size = 0;
                FILE *fp;
                strcpy(filename2, tmp);
                printf("Server receiving file name...\n");
                //first 'read' receives the file name
                fp = fopen(filename2, "wb");
                if(fp == NULL)
                    printf("File could not be opened.\n");
                    exit(1);
                
                printf("Server receiving file...\n");
                while((x = read(sd, buf, sizeof(buf)) > 0)) //second read now retrieving the file
                    printf("Server creating new file...\n");
                    fwrite(buf, 1, file_size, fp);
                
            fclose(fp);
            printf("The server has received the requested document.\n");
         

客户端:

 else if(putCommand)
            
            char *tmp = buf + 4;
            char filename[MAX_BLOCK_SIZE];
    
        long file_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, filename, sizeof(filename)) < nr))     //sending the file name to the client first
                printf("Error sending client's filename.\n");
            
            
            //size_t file_size;
            printf("Client sending file...\n");
            fseek(fp, 0, SEEK_END);
            long filesize = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            
            while((file_size = fread(buf, 1, MAX_BLOCK_SIZE, fp)) > 0) //sending the file
            
                if ((x = write(sd, buf, filesize) < 0))
                    printf("Error sending client file.\n");
                
            
            
            fclose(fp);
            
            
            

【问题讨论】:

if((x = read(sd, buf, sizeof(buf)) &lt;= 0)) read 返回一个负数出错 另外,在服务器端,您需要继续接收,直到收到所有字节。您不能假设单个 read 会获取所有数据。 为什么不使用stat() 来获取大小? @n.'pronouns'm。我已将其更改为 > 0,这是我的错误,抱歉 while((x = read(sd, buf, sizeof(buf)) &gt; 0)) 毫无意义。您想知道read 能够读取多少字节,并使用该数字。那将是while((x = read(sd, buf, sizeof(buf))) &gt; 0) fwrite(buf, 1, x, fp); 注意括号和x 的使用。 【参考方案1】:

这几乎是一个错字。在接收方,您有:

long file_size = 0;
...
    while(...)
        ...
        fwrite(buf, 1, file_size, fp);

所以你一直写 0 字节。

标准方式是:

    while((x = read(sd, buf, sizeof(buf)) > 0)) //second read now retrieving the file
        printf("Server creating new file...\n");
        fwrite(buf, 1, x, fp);     // write the number of bytes returned by previous read
    

最后一句话,我希望buf是一个真正的数组而不是一个指针...

【讨论】:

感谢您指出这一点。我已经进行了这些更改,并且接收端的相同 while 循环永远不会结束。当我通过终端结束程序时,创建的文档中只有我发送的文档中的第一个字母

以上是关于在C中成功发送和接收文件大小的主要内容,如果未能解决你的问题,请参考以下文章

文件大小过多的 Java

邮件发送超大附件,上传下载特别慢,怎么解决?

C中的服务器/套接字编程:数据未正确发送/接收?

在 golang 中更新 grpc 的接收和发送消息大小

(14)C#的网络接收和发送的各种大小端字节转换

C 语言文件操作 ( 配置文件读写 | 写出或更新配置文件 | 函数形参设置 | 确保打开文件成功 | 统计文件大小 )