0

I have searched for a neat explanation of how to use sockets to receive and send files in linux, but i can't find a solution that even works a little bit. I have a c++ server on linux, and a client which runs in java.

I need it to do the following:

  • Client needs to be able to send text-commands towards the server.
  • Client needs to be able to send/receive files towards the server.
  • Server gets the following command when receiving a file: PUT < saveLocation > < filecontents >
  • Everything gets closed by "\n".

I've got a lot of code written already, and am able to send commands back and forth between client and server. But now i'm stuck on sending/receiving a file on both the client and server.

What steps should i take, to be able to receive a command from the client which says "PUT /map1/test.pdf somefile" and also receive the actual file?

If code is needed pls ask, and i'll post it, but i don't which code blocks can be helpful.

3
  • The key is, if it's a large file, to send the file in pieces. Use a buffer to read/write the file in smaller parts. If this is not what you are looking for, you need to be more specific in your question. Commented Dec 21, 2012 at 12:27
  • C++ or java is not relevant here. The thing is: you have a socket on both sides and you send data both ways. You have to design a protocol that will allow you to do what you want (just as FTP is an example protocol to achieve what you seem to need). Then you implement it on both sides and you're done. You can look for example protocols and build from them. Commented Dec 21, 2012 at 13:05
  • If Everything gets closed by "\n". you have two big restrictions. You can't send binary files and you can't send text with more than one line. I would rethink the protocol. Commented Dec 21, 2012 at 13:49

2 Answers 2

1

Why not use an FTP server instead? FTP was, after all, designed to do just this. You could set up a FTP daemon on your server and use FTPClient from Apache commons-net.

If you are hell-bent on reinventing the wheel, the MIME-multipart approach (used when posting files over HTTP or sending them as attachments in emails) is to define a boundary and then BASE64-encode the binary file-content to be able to send it as ASCII text.

The boundary should be a string of text sufficiently complex so as to be unique. Your "transaction" would then look something like

PUT <filename> boundary=A_COMPLEX_BOUNDARY_STRING<newline>
<BASE64 encoded binary file content>A_COMPLEX_BOUNDARY_STRING

When receiving on the server, you parse the filename, the boundary value and then you know that everything after the first newline to the boundary string is the BASE64 encoded binary file data.

Sign up to request clarification or add additional context in comments.

Comments

0

A socket merely transfers bytes of info -- it does not "know" whether those bytes are from a file, a message, or are randomly generated. It is entirely up to the sending and receiving software to organize the bytes so that the receiver can interpret the bytes sent.

Often for simple messages, senders just end each message with an ASCII (or some encoding) end-of-line. But that isn't appropriate for data that might contain an end-of-line byte as valid data.

The simplest thing, it seems to me, is to send counts of the bytes being sent in each message. I wouldn't try to send the entire file in one message unless there were outside reasons why I should; I would break the file up into 'chunks'; I would define a message to put the number of bytes in a particular chunk as the first byte, then send the rest of the chunk, then repeat until all chunks are sent.

The receiver obviously then has to know that the byte count is the first thing sent, how many bytes it is, which byte(s) (high or low order) is/are first, etc. The receiver then has enough information to read all the chunks and put them back together.

I would also include a "handshake", i.e., the receiver returns a message after each chunk indicating that it received that one; otherwise you could spend a lot of time sending bytes only to discover that your receiver is down for some reason.

2 Comments

Why would you implement something that is already intrinsic to the TCP/IP protocol stack? The IP protocol will break your data into packets, the TCP protocol does handshaking and acknowledgment of transfer.
You have a point about breaking it up; there are situations in which I wouldn't bother with that. As for the handshake: the transport protocol will, indeed, ensure that packets are transferred and put back into their original order, but it will not necessarily give a meaningful error to the application if they are not. The sending application needs to know that the entire message was received correctly, and I think that is best done by having an acknowledgement sent from the receiver back to the sender.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.