I'm sending a file from the client to the server.
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.