multiple filetransfer via sockets

Started by
2 comments, last by hplus0603 10 years, 5 months ago

Hey guys I have a general network programming issue I hope someone here can help with. I'm familiar with win32 general API programming as well as the socket APIs. My problem is dealing with multiple simultaneous file transfers being sent in a way my code doesn't expect.

Here is the overall idea:

Server initiates a file transfer via "sendfile" command and basically my client acknowledges and parses the data in the same recv loop as used for the communications channel.

Server sends over socket "sendfile:filename:size" followed by the actual file in a format like this:

"sendfile:[filedata]"

"sendfile:[filedata]" until the file is sent in its entirety (2048 byte buffer)

The client simply:

while(connected)

{

if(strcmp(recvbuffer,"sendfile:",9)==0) { handlefile(recvbuffer[9],len-9);

else if() ; blah blah

}

This works perfectly however sometimes the data will be received by the client without the initial "sendfile:" part so my parsing code will miss some data and the file becomes corrupt.

My issue is that sometimes the underlying network will send half the data followed by the other half but my code expects each recv buffer to be preceeded by the string indicating a transfer is taking place.

I imagine file transfer is a very well understood topic but I'm not sure how to solve this problem. Any ideas/suggestions are greatly appreciated!

Thanks again.

Advertisement

TCP is not a packet protocol, it is a stream protocol. Calls to send() are not matched 1:1 to calls to recv().

enum Bool { True, False, FileNotFound };

You are certainly right.

How would you suggest I accomplish what essentially is file transfer over the same channel as communication? Or even simply two file transfers over the same channel. And by channel I mean the one socket connection in case it wasn't clear.

The FAQ has information about this, as does many threads within this forum.

You need to build a packetized structure yourself, where each packet contains a type code, a size field, and then that much data.

When reading from the TCP socket, you keep buffering data until the buffer contains at least one full packet, then you remove and handle that packet from your buffer, and repeat.

So, for example, you could have the following packet headers:

struct start_file_transfer {
  uint16 p_type;
  uint16 p_size;
  uint16 transfer_id;
  uiint64 file_size;
  ubyte name[];
};
 
struct file_transfer_chunk {
  uint16 p_type;
  uint16 p_size;
  uint16 transfer_id;
  uint64 chunk_offset;
  ubyte data[];
};
 
struct end_file_transfer {
  uint16 p_type;
  uint16 p_size;
  uint16 transfer_id;
};

Now, send a start packet, followed by some number of chunk packets (with, say, 48 kB of data each,) followed by an end packet; that completes a particular file transfer operation. Because each separate transfer is identified by an id, you can tell each incoming packet apart.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement