views:

273

answers:

4

I have a multi-threaded server that handles client requests, and makes new threads for each one that is connected. This is working great and I am able to send "text" messages back and forth to the server without a problem. Like a chat system.

Now I have in mind a way to be able to send files across these client connections to the server, but every single example I see in java always has a hard-coded file name on server / client side - but I want to set my own for flexibility. And I would love if it were not only able to not only receive files but also receive "text" messages on the same port simulatanously.

I have an idea whereby the "text" message port I have at the moment, tells the server a file is going to be sent from a client, then the server opens up a "file transfer" port, just for file transfers. That way the "text" port could specify the name etc of the file. And the other port could send the files quite happily, without interruption.

Does anyone know a better way to do this though? I don't really want to use two ports, it seems a bit messy. I would prefer to make a separate thread on the server side to deal with the file transfer and also deal with "text" message at the same time, if this is even possible?

Thanks in advance, I hope I have been clear enough :)

A: 

Chuck the file in pieces and send them along the "normal" line.

Something link:

  • text message
  • start file (id <-- id number invented by the client, filename)
  • file piece (id, with some bytes in a byte[])
  • end file (id)

the server receives the start file and start a new structure saving: * client id * invented id (and name why not! :)

next with each file piece add that bytes (maybe writing to disk or something)

The end file meesage would say: ok, flush and close!

The server can save the files in a map, mapping from a Key object (clientid+fileid) to the temp structure.

helios
And of course, the client have to have a secondary thread reading the file and sending the chunks. If the client send the text messages onto the UI thread, the the other thread has to sync. Anyway, as it HAS to be sync, I would make a sync'ed method to send all types of message.
helios
+1  A: 

Sounds like you're re-inventing FTP. You might want to look at FTP servers implemented in Java. WebDAV as well.

Licky Lindsay
A: 

Waht you describe is pretty much how FTP works. And yes, it is messy, especially the part where the server opens a port, because that simply does not work in this age of firewalls and NAT. Thus, FTP had to add a "passive mode" where the client opens the additional port.

But there's really no reason to have separate ports. Why not simply have one kind of text message that announces "here comes a file", and send the file right afterwards on the same port?

Michael Borgwardt
+3  A: 

Sure, it's easy. You just have to specify the message type first. Either with a byte or with a line of text.

The easiest way would be with a single byte like this:

//to send
Socket s = ...
OutputStream os = s.getOutputStream();
if(messageIsText()){
  os.write(0);
  //send text
else{
  os.write(1); 
  //send file
}

then in your server you could do this:

Socket s = serverSocket.accept();
InputStream in = s.getInputStream();
int firstbyte = in.read();
if(firstbyte = 0){
   //read text
}
else{
   //read file
}

Now, that's not very flexable, but there are lot of things you can do. I would actually recommend you read RFC 2616, that's the specification for HTTP. You don't need to read the whole thing, and just the enough to write a simple web server. It's actually really easy (HTTP is a really simple protocol at the core, although it has a lot of advanced features now)

If you really want to learn network programming, try writing an HTTP server. That might sound daunting, but don't worry, it's actually not that hard at all.

Chad Okere