2

I'm coding a server/client application pair in Java, as I learn about it. I have basic functionality of sending a message to the server and parsing it but in thinking about the big picture of their communication, I'm stumped about where to go from here.

Both the client and the server have to be able to initiate an exchange of data so I need to have one thread reading at each side, at all times. On top of that, when one initiates an exchange, it needs to listen for the reply. If I do that, though, I'd have two threads reading data, which I guess wouldn't end well since, from my understanding, I wouldn't be able to make sure the data gets read in the thread I want.

I see a few options but I'm not confident at going too far with each solution since my knowledge doesn't let me think too far ahead.

  1. Use only the first thread that was originally waiting for data before the exchange, to also read the reply for the query that was just sent by a different thread, and forward the data where it belongs.

    This sounds difficult. If I read the data in the same thread that requested it, it would be very straightforward compared to this.

  2. Start reading the InputStream in the same thread that requested data and make the thread that was originally listening, wait.

    My problem with this is that, if there's other data arriving by the same client that is unrelated with the query that was just made, it would be fetched by this thread instead of the other one, which kinda defeats the purpose of reading the data here.

  3. Establish another connection from the client, to another port, after the first is established. Then I could use one socket for exchanges initiated by the other side, and the other to listen for replies of queries made in the meantime.

    This way I'd know exactly what is going where, but wouldn't I have this same problem further down the road if I have two queries waiting for data at the same time?

This sounds like simple functionality, trivial to find in many applications, so I'm guessing there's some tried and true method out there and there's no reason for me to try and reinvent the wheel here.

So, to sum it up, what's the recommended way to set up client/server applications that can cope with possibly overlapping dialogs, initiated by either one, at unpredictable times?

I started to modify some parts of the question to make it a bit clearer but I ended up almost rewriting it completely. If it's still a bit confusing is because I am confused. I think I'm missing some simple point but I haven't been able to find examples that show this.

2 Answers 2

1

Using multiple connections per user could be problematic because you will hit the servers connection limit earlier when you have a lot of users.

TCP, however, has the advantage that packets are always received in whole and in order. You can use that to implement your own application-level session handling system which works in a preemtive ("time-sharing") multi-threading way.

When there are multiple file downloads taking place at the same time, you could split each file transfer into individual packets and prefix each packet with an identifier which says to which file transfer it belongs. Then you put the packets of each transfer into a queue and process these queues in round-robin order. That means when you have 3 file transfers A, B and C consisting of 3, 5 and 7 packets each, you would send these 15 packages in the order ABCABCABCBCBCCC. Make sure that you are able to add a new queue at any time between sends so that you can enter a new transfer while other transfers are running.

On the other side you read the prefix of each packet to find out to which file transfer it belongs and append it to the corresponding input stream.

A good API to manage all this on Java is non-blocking IO. You should use that anyway on a server which handles a lot of users, because that way you avoid to create individual threads for all users.

0
0

A common way to do it would be to have the client maintain a persistent TCP connection to the server (i.e. once the client connects to the server, it stays connected until the client quits).

Since TCP connections are bi-directional, the client and the server are both free to send data across the TCP socket at any time.

(Note that the more difficult part of this setup is the receiving of data: Instead of doing a synchronous model where your client sends something, then blocks waiting for the return data to come back, your client must be ready to receive data from the server at any time... but it also needs to be able to handle other tasks, such as GUI events, simultaneously. This can be done by dedicating a thread to receiving data, and/or by using an asynchronous I/O model)

1
  • 1
    Thanks for the help but I think the question is past that stage. I have updated it and I think it's much more clear now.
    – Smig
    Dec 20, 2012 at 19:34

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.