简体   繁体   中英

Program stuck writing contents to the file in C

I'm sending a file from the client to the server.

  • Client sends filename
  • Server receives filename
  • Client sends file size
  • Server receives file size
  • Client sends file contents
  • Server receives file contents

When I print out the file size that I sent, it is the exact number of bytes as the file I wish to send so that's fine. The issue is that the server (receives) doesn't seem to exit the while loop when writing to the new file. I know this because the final print statement printf("The server has received the requested document\\n"); is never reached and it just hangs. What could be causing this?

Client snippet (sends):

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

Server snippet (receives):

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

After I exit the program by force, I can actually see that the file has been copied. Just doesn't exit that while loop to let me go back to the client.

Time for some basic debugging. I'd suggest changing your read loop to something like this:

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

Then run it, piping the output through less or some other pager, it should then hopefully become clearer what's actually happening.

Feel free to post the output of this modified code (in a comment, or in the actual question), we'll no doubt be able to help with the analysis.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM