views:

41

answers:

3

I am writing a socket server, that when the client requests, the server will send some files, one after the other. Supose I have file1, file2, and file3 to be transfered. How can I know on the client side, if the file1 has finished, and file2 has started? For messages I am using a DELIMITER character (\r\n). Should I use thise for files too? I dont think its a good idea to stay looking after a DELIMITER inside file´s bytes.

And I need to use the same TCP connection as the messages for transfering those files.

+1  A: 

Send file length before file contents. That way the receiver knows how many bytes belong to which file.

gpeche
+2  A: 

There are basically two ways to do this:

  • Use a file separator character, and implement a mechanism for "escaping" the separator if it appears in the content of a file.

  • Send the length of the file before sending the file.

The first approach requires both the sending and receiving end to examine each byte of each file transmitted. The second approach is better, because it avoids this. However, it assumes that you can determine the length of the file before you send it ... which may not always be the case; e.g. if you are generating the files on the fly, writing them directly to the socket stream.

There is a variation on the second approach epitomized by HTTP's "chunk encoding" scheme. (Thanks @BalusC for reminding me.) This involves splitting the file and sending it as a sequence of "chunks" preceded by chunk sizes. This has two advantages compared to the "size + file" approach:

  • The sender does not need to know the file size before hand.
  • It is possible (given suitable protocol design) for either the send or receiver to cancel/skip sending of one file and continue with the next one. (With the simple "size + file" approach, the protocol cannot support this because the sender and receiver cannot resynchronize reliably.)
Stephen C
When the file length is unknown, you'd have used [chunked encoding](http://en.wikipedia.org/wiki/Chunked_transfer_encoding) in HTTP. It may be useful to copy/mimic it.
BalusC
@BalusC - good point.
Stephen C
+1  A: 

Instead of a delimiter you could have the receiving end detect when the input side of the socket is empty and send a query to the sender on the output side of the socket. If it was just delay, the sender replies with 'sending file X' and the receive knows to keep waiting. If the transfer was complete the sender replies with 'transfer complete (###bytes)' so the receiver knows to be ready for the next file.

It adds a short delay between files but is a simple way to use the same socket for multiple transfers without needing to use delimiters which need escaping.

Kelly French
seems like a good idea, but if was just delay, the server might send bytes of the file before answering the query. Imagine: There no bytes available, so client asks if file is finished? Before server gets the message, the delay is over and some file bytes arrive, the client will think its the reply and not bytes from the file, so I will have to check if those bytes are a string from the server, rigt?
fredcrs
The client waits for the response before deciding if the file is complete. The server doesn't send any more data until the client asks if the file was done.
Kelly French