user8535817
user8535817

Reputation:

files are damaged after downloading from an ftp server

Here's what I have:

    send(serverSocket, "RETR user.png\r\n", 15, 0);

    int iResult;
    int size = 0;

    do {

        iResult = recv(dataSocket, buffer, 30000, 0);
        if (iResult > 0) {
            printf("Bytes received: %d\n", iResult);
            size = size + iResult;
        }
        else if (iResult == 0)
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while (iResult > 0);

    cout << "the full size: " << size << endl;

    ofstream fout("test.png", ios_base::binary);
    fout.write(buffer, size);
    fout.close();

Here, I download a file into a buffer, and then create a file with the same type and write this buffer into it. The problem is that I can't open this file because it is damaged.

I tried to open this file using a hex editor, and it differs from the good one, but not that much. There's just some extra bytes and the whole data are shifted a bit because of them. Where did they come from and how to get rid of them? What's wrong with my program?

hexidemical representation (test.png is the one I downloaded, user.png is the good one, I downloaded it using my browser). I've marked 2 extra values, but there are more of them. I hope it'll be useful to figure out what's the deal. Thanks in advance.

Upvotes: 0

Views: 236

Answers (1)

selbie
selbie

Reputation: 104559

This is your problem:

iResult = recv(dataSocket, buffer, 30000, 0);

The beginning of "buffer" gets overwritten with every loop. You want to be appending to the end of the data already written, not overwriting it.

This is what you want:

iResult = recv(dataSocket, buffer+size, 30000-size, 0);

I'm assuming buffer is an array of chars (or unsigned chars, or anything with sizeof(1)). If not, then this:

char* ptr = (char*)buffer;
iResult = recv(dataSocket, ptr+size, 30000-size, 0);

The other bug is because you're in ASCII mode with the server. All those 0A bytes are getting interpreted as an Unix linefeeds, and it's happily inserting the Windows carriage return, 0D, chars before each. I'm not sure if this is because the server is sending it that way, or your I/O calls to save aren't in the binary mode. But whenever I do an FTP transfer, I always make sure to type "binary" at the command prompt so that the ASCII help isn't applied.

Look at the list of FTP commands, you may need to send the "TYPE" command to force binary mode. And if that's not it, it's quite possibly the ofstream is...

Upvotes: 3

Related Questions