Search code examples
cfileftpprotocolsfile-transfer

FTP protocol STOR cmd receiving file correctly in c


I'm working at a simple FTP-Server (just for fun) and the last step is to store a file with the "STOR" cmd.

rec_file method:

int rec_file(char *filename, int sockfd){
    int bytes_read;
    char buffer[4096];
    FILE *f = fopen(filename, "wb");
    
    while (bytes_read=read(sockfd,buffer,sizeof(buffer))){
        fwrite(buffer , 1 , sizeof(buffer) , f);
    }
    fclose(f);

    return 0;
}

Test File a.txt:

TEST123
456
789
TEST!!

sent file a.txt:

TEST123
456
789
TEST!!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  AÛD              Ìk     P      ™sB             ÃB     p      Àa           ðÿÿÿÿÿÿ                        P              #       €Ìk      Ìk     @      dB         %                         0       %       Øa    P                  0                           |   w   n   [    Ìk     8Y
ý  %       8Y
ý  #               Àk             W.B                             G
ý  8Y
ý  QH     /home/felix/ftp                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ¨A                     PQ
ý   Ãk     R
ý  `Q
ý         =F         )                   -rA     ÿÿÿÿÿÿÿÿ Çk     ¨      *       0k    1„A              Çk            -rA     ßJI      Çk     ¨             0k    1„A              Çk            ¨           

So what am I doing wrong?


Solution

  • Your code may write more bytes to the file than you have received from the socket.

    The return value of read which gets stored in bytes_read will tell you how many bytes have actually been read. Even if the amount of data is large, read may not always read a full buffer, it may return a smaller number. You should also handle negative values as errors.

    The code below has a very simple error handling. In a real application you might have to retry the read call on certain errno values instead of stopping to read data.

        while ((bytes_read=read(sockfd,buffer,sizeof(buffer))) > 0){
            fwrite(buffer , 1 , bytes_read, f);
        }
    
        if(bytes_read < 0) {
            perror("read failed");
            /* maybe other error handling  */
        }