程序卡住将内容写入 C 中的文件

Program stuck writing contents to the file in C

我正在从客户端向服务器发送文件。

当我打印出我发送的文件大小时,它是我希望发送的文件的确切字节数,所以没问题。问题是服务器(接收)在写入新文件时似乎没有退出 while 循环。我知道这是因为最后的打印语句 printf("服务器已收到请求的 document\n");永远不会到达,它只是挂起。可能是什么原因造成的?

客户端代码段(发送):

 else if(strcmp(shortCommand, "put") == 0){
            
            
            char *tmp = buf + 4;
            char filename[MAX_BLOCK_SIZE];
        size_t size, bytes_read, bytes_written;
        int x;

            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 ((x = 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");
            
            fseek(fp, 0, SEEK_END);
            size = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            printf("Sending file size\n");
            
            if((write(sd, &size, sizeof(size))) < 0){ //sending filesize
                printf("error sending file size\n");
            }
            
            printf("Sending file\n");
            while((bytes_read = fread(buf, 1, sizeof(buf), fp)) > 0){ //sending file contents
            
                if ((bytes_written = write(sd, buf, bytes_read)) < 0){
                    printf("Error sending client file.\n");
                }
            
            }
            printf("bytes written: %ld\n", bytes_written);
            fclose(fp);
            }   
    }

服务器片段(接收):

if(strcmp(shortCommand, "put") == 0){
                char *tmp = buf + 4;
                char filename2[MAX_BLOCK_SIZE];
                size_t  filesize;
                size_t total_bytes_read = 0;
                ssize_t bytes_read = 0;
                size_t error;
                FILE *fp;
                strcpy(filename2, tmp);
                printf("Server receiving file name...\n"); //filename is received on the first read before this IF
                fp = fopen(filename2, "wb");
                if(fp == NULL){
                    printf("File could not be opened.\n");
                    exit(1);
                }
                
                printf("Server receiving file size...\n");
                
                if((error = read(sd, &filesize, sizeof(filesize))) < 0){ //receiving file size
                    perror("Error reading filesize\n");
                    exit(1);
                }
                
                printf("Filesize is: %ld \n", filesize);
                
                while(total_bytes_read < filesize){
                    while((bytes_read = read(sd, buf, sizeof(buf))) > 0){ //receving file contents and writing to file
                        fwrite(buf, 1, bytes_read, fp);
                        total_bytes_read += bytes_read;
                    if(ferror(fp)){
                        perror("error");
                        fclose(fp);
                    }
                    }
                }
                printf("The server has received the requested document.\n");
                fflush(stdout);
                fclose(fp);
    }

我强行退出程序后,居然看到文件已经被复制了。只是不退出那个 while 循环让我回到客户端。

是时候进行一些基本的调试了。我建议将您的读取循环更改为如下内容:

while (total_bytes_read < filesize) {
    printf("DEBUG A: total=%zu, size=%zu\n", total_bytes_read, filesize);
    while ((bytes_read = read(sd, buf, sizeof(buf))) > 0) {
        printf("DEBUG B: read=%zd\n", bytes_read);
        fwrite(buf, 1, bytes_read, fp);
        total_bytes_read += bytes_read;
        printf("DEBUG C: total=%zu\n", total_bytes_read);
        if (ferror(fp))
            printf("DEBUG D\n");
            perror("error");
            fclose(fp);
        }
        printf("DEBUG E\n");
    }
    printf("DEBUG F\n");
}
printf("DEBUG G\n");

然后 运行 它,通过 less 或其他寻呼机输出,然后它应该会更清楚实际发生的事情。

请随意 post 此修改代码的输出(在评论中,或在实际问题中),我们无疑能够帮助分析。