0

I tried and looked up TONS of pages over the net, found NOTHING that fits windows and is working always, I tried this one over the TCP protocol (streaming byte-by-byte untill you bump into 3 - I tried it on files with no 3 in it :PPPP and by 3 I mean the ASCII value 3 and not the digit '3').

Server side:

int sendFile(SOCKET s, const char* file_path)
{
    FILE* fp = fopen(file_path, "rb");
    int i, err = 0, bytesSent, isOk = 1;
    char ch = 0;
    if(!fp)
    {
        fclose(fp);
        return 1;
    }
    while(ch != EOF && isOk)
    {
        fread(&ch, sizeof(char), 1, fp);
        if(ch != EOF)
        {
            bytesSent = send(s, &ch, sizeof(char), 0);
            if(bytesSent <= 0)
            {
                 return 1;
            }
        }
        else
        {
            isOk = 0;
        }
    }
    ch = 3;
    bytesSent = send(s, &ch, sizeof(char), 0);

    fclose(fp);

    return 0;
}

Client side:

int recvFile(SOCKET s, const char* file_path)
{
    FILE* fp = fopen(file_path, "wb");
    int bytesRecieved;
    char ch;
    if(!fp)
    {
        fclose(fp);
        return 1;
    }
    bytesRecieved = recv(s, &ch, sizeof(char), 0);
    if(bytesRecieved <= 0)
    {
         return 1;
    }
    while(ch != 3)
    {
        fwrite(&ch, sizeof(char), 1, fp);
        putch(ch);
        bytesRecieved = recv(s, &ch, sizeof(char), 0);
        if(bytesRecieved <= 0)
        {
            return 1;
        }
    }

    fclose(fp);

    return 0;
}

The sockets are functioning well and sending and receiving well (I'm talking about sending regular messages, without the functions). It's not returning 1, it's just turns into an infinite loop. No idea why it's not working, any idea ? I'm totally desperate.

Zach
  • 11
  • 4

2 Answers2

0

Instead of comparison with EOF, you should use the feof function while reading from file. EOF is just an error code returned by some functions, not an actual character in the file.

Also, I notice that the thing with the character 3 seems a way to signal the end of the file. You should consider normalizing the data transfer. You could send at the beginning of the communication the size of the file, and the client reads exactly the size of the file, to avoid having problems with files that contain that character (3 is still a valid character).

For inspiration, take a look at an old project of mine that implements this behavior (although it's linux only).

Paul92
  • 8,827
  • 1
  • 23
  • 37
  • http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong But I'll try :P – Zach Aug 07 '14 at 15:13
  • By the way, how should I send the length ? Of course I can use itoa() to turn it to a string but isn't it better to send 4 bytes of an int and than with a void* treat it as an int* ? – Zach Aug 07 '14 at 15:14
0

I once fell in trouble reading on tcp socket by chunks smaller than what was used for writing. On a socket you write packets of a determined length (write or send), and implementation may discard the end of the packet if read size is shorter.

From man page on recv : All three routines [recv, recvfrom, recvmsg] return the length of the message on successful completion. If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from.

When reading, you should allways use a buffer of a size at least equals of the longest buffer used in writing.

You could dump what you receive to confirm.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252