2

Let me start by saying this is a homework assignment and I am not a c programmer. I have been working on this for days and I am stuck. I have read the beej guide from cover to cover and have been searching google for a week, it's time to ask for help. I have a client-server TCP socket application that sends and receives messages as expected, now I need to implement simple file upload/download functionality.

The code below almost works but it adds 4 bytes to the beginning of the copied file, two non-printable characters followed by \00\00 and the client no longer responds.

The client is connected by a non-blocking socket using the select command.

I know there is lots of room for improvement but can someone help me get started?

// Server

void put (int sockfd, char *localfile) { // Get file Size FILE *file; int size; file = fopen(localfile, "rb"); fseek(file, 0, SEEK_END); size = ftell(file); fseek(file, 0, SEEK_SET); //Send file Size write(sockfd, &size, sizeof(int)); //Send file as Byte Array char send_buffer[size]; memset(send_buffer, 0, sizeof(send_buffer)); //while(!feof(file)) { // fread(send_buffer, 1, sizeof(send_buffer), file); // write(sockfd, send_buffer, sizeof(send_buffer)); // memset(send_buffer, 0, sizeof(send_buffer)); //} int sent; while((sent = fread(send_buffer, sizeof(char), sizeof(send_buffer), file)) > 0) { if(send(sockfd, send_buffer, sent, 0) < 0) { fprintf(stderr, "[Server] ERROR: Failed to send file %s. (errno = %d)\n", localfile, errno); break; } memset(send_buffer, 0, sizeof(send_buffer)); } fclose(file); } 

//Client

void get(int sockfd, char *remotefile) { FILE *file; int size; //Read file Size read(sockfd, &size, sizeof(int)); //Read file Byte Array char p_array[size]; memset(&p_array, 0, sizeof(p_array)); read(sockfd, p_array, size); //Convert it Back into file file = fopen(remotefile, "wb"); fwrite(p_array, 1, sizeof(p_array), file); fclose(file); } 
2
  • Just a warning, read this StackOverflow thread to learn how to correctly use feof(). Commented Mar 29, 2013 at 5:35
  • Could it be the simple case of you not initializing your arrays like char send_buffer[size] = { 0 }; and char p_array[size] = { 0 };? Commented Mar 29, 2013 at 5:57

1 Answer 1

3

You are making the usual error of ignoring the read count when reading the socket, and assuming that each read fills the buffer. You can't assume that.

Your send loop doesn't make that mistake. So, use that as a model, but redo it for receiving so as to use read() instead of fread(). You should then see that there's no need to allocate a buffer the size of the file, and there is therefore no need to send the filesize ahead of the file, unless you're planning on keeping the connection open for another purpose.

There's also no reason for any of the memset() calls.

Sign up to request clarification or add additional context in comments.

6 Comments

EJP, thank you for the reply. I don't think I understood your advice. I changed the code as follows but now all I get is a 4 byte file with only the non-printable characters and the \00\00
void put (int sockfd, char *localfile) { // Get file Size FILE *file; int size; file = fopen(localfile, "rb"); fseek(file, 0, SEEK_END); size = ftell(file); fseek(file, 0, SEEK_SET); write(sockfd, &size, sizeof(int)); char send_buffer[size]; int sent; while((sent = read(sockfd, send_buffer, size)) > 0) { if(send(sockfd, send_buffer, sent, 0) < 0) { fprintf(stderr, "[Server] ERROR: Failed to send file %s. (errno = %d)\n", localfile, errno); break; } } fclose(file); }
void get(int sockfd, char *remotefile) { FILE *file; int size; //Read file Size read(sockfd, &size, sizeof(int)); //Read file Byte Array char p_array[size]; int bytes_read; //read(sockfd, p_array, size); while((bytes_read = read(sockfd, p_array, size)) > 0) { if(recv(sockfd, p_array, sizeof(p_array), 0) < 0) { fprintf(stderr, "[Client] ERROR: Failed to recv file %s. (errno = %d)\n", remotefile, errno); break; } } //Convert it Back into file file = fopen(remotefile, "wb"); fwrite(p_array, 1, sizeof(p_array), file); fclose(file); }
I'm sorry for the formatting, I can't figure out how to format code in a reply.
also, yes, I need to keep the connection open so the client can perform other operations after the file is uploaded/downloaded.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.