user2158382
user2158382

Reputation: 4510

C: Sending and Receiving a file over a socket

I am trying to implement a distributed p2p file sharing system where a peer can both send and download files from other peers. But, I am having some trouble downloading and saving the file to a directory.

Here is where I send the requested file

while(!feof(requestedfile)) {
    bytes_read = fread(buf, 1, sizeof(buf), requestedfile);
    send(clientSock, buf, bytes_read, 0);

}

When I try to download, I do the following

while(recv(clientSock, currentLinePointer, 1, 0) != 0) {
    currentLinePointer++;
}

I am new to C, but I know I have 2 issues

  1. How do I perform a more efficient read? If I read 1024 bytes at a time, at the last block of data, there only may be half of the 1024 bytes filled. Will the other 512 nonsense bytes cause errors in my file? (I know bad things happen to pictures when you try to read and save a jpg with nonsense bytes at the end)
  2. Now that I have read the file, how do I save that file? Say a peer request "hello.jpg". The setup I have can send and read that file, but now how can I save that file to the requesting peers directory "PATH/Pictures/"

Upvotes: 0

Views: 1378

Answers (3)

Havenard
Havenard

Reputation: 27924

recv() returns the number of bytes received, 0 if connection is closed and -1 on error. That basically answers your question.

You should also keep track of the value returned by send(). It returns the number of bytes sent, or at last put in buffer for sending. It will not always send everything you tell it to if the buffer is full or the connection is lost. Keep track of its return value to control the send buffer usage and avoid gaps in the file being transfered. You may have to perform a new send() call to send the part of the data it refused to in a previous call.

Upvotes: 0

Philip
Philip

Reputation: 281

I suggest you read 4096 bytes at once since this is the standard size of a disk sector nowadays (http://en.wikipedia.org/wiki/Disk_sector):

char* buffer = (char*)malloc(4096), *position = buffer;

while((bytes_read = recv(clientSock, position, 4096, 0) > 0)
{
    if(fwrite(position, 1, bytes_read, localFile) != bytes_read)
    {
        // do some error handling here
        break;
    }
    position += 4096;
}

// and here

free(buffer);

Upvotes: 0

bizzehdee
bizzehdee

Reputation: 21023

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx

If no error occurs, recv returns the number of bytes received

You need to know what the return value of recv is and only write that number of bytes to your file.

Upvotes: 1

Related Questions