Home > Software engineering >  How to send file and filename through socket in C?
How to send file and filename through socket in C?

Time:09-15

I am trying to send a file and its name through a socket in C.

The relevant server code is:

char file[18];
    memset(file, 0, 18);
    file[17] = '\0';
    int recvd =  recv(newsock, file, 16, 0);

char local_file_path[200];
memset(local_file_path, 0, 200);

if(recvd == -1 || recv == 0) {
    fprintf(stderr, "File name not received");
    continue;
}

strcat(local_file_path, "/home/ubuntu/results/");
strcat(local_file_path, file);
FILE* fp = fopen(local_file_path, "wb");

char buffer[4096];
while(1)
{
    recvd =  recv(newsock, buffer, 4096, 0);
    fwrite(buffer, sizeof(char), recvd, fp);
    if(recvd == -1 || recvd == 0) {
        fclose(fp);
        break;
    }
}
close(newsock);
}
close(servSock);

The relevant client code is:

char* my_16_long_fname = "filename1234.txt"
int ret = send(sock, my_16_long_file_fname, strlen(my_16_long_fname), 0)

This code, however, has been creating lots of undefined behaviour such as: 1.Receiving garbage filenames filled with garbage 2.Receiving empty files (so a name with nothing inside - could be some other bug but possibly due to this)

I have thought about a few solutions:

1.Diferentiate file types by signature/header and generate a file name on the server side. Besides this being a cheap solution which doesn't teach me how to actually solve the problem, it doesn't work with the logic i'm using, where sometimes I send error codes instead of file names after opening the socket.

2.Iterate over the recv'd buffer on the first call to recv until I encounter a '\0' character. Then write the remainder of the buffer as binary data and keep on receiving data as usual.

Is this the most efficient/simplest and solid solution to this issue, which will prevent any undefined behaviour?

CodePudding user response:

There is no way your current code could possibly work. If the filename is always one character, your code can read too many characters. If your filename is always the same number of characters but more than one character, your code can read too few characters. If the filename is a variable number of characters, your code could read a smaller number than was sent.

So there is no sending protocol for which this could be valid receiving code.

Until you are an expert on writing networking code, always follow these two steps:

  1. Document the protocol.

How many bytes does the filename occupy? Is it a fixed number or a variable number? Is it always followed by a zero byte?

  1. Implement the protocol.

For example, your code reads up to 16 bytes for the filename. But it never checks if it received the whole file name. What if it only received a single byte?

  • Related