Multiple threads reading and writing frmo single client socket

Hi,

I'd like to ask if it's possible for multiple threads to write on a client socket at the same time, then wait and read a response from the server on the same socket. I plan to create client socket, which can send and receive messages to and from the server concurrently. If not what's the best design? Do I have to queue the outgoing messages while waiting for the reply for the last message sent?

Thanks in advance.

[442 byte] By [blood_aspa] at [2007-10-3 3:36:39]
# 1

On client side you should have one synchronized procedure which will send message through socket (if you want some one for all threads) to server and two threads for reading and writing to socket.

On server side you should have two threads, for reading and writing, for each client. If you want to send one message to all clients, you should have some class which will take care about all clients (to have Hashtable or some map with names and instance of threads)...

I hope I was enough clear :)

boba5555a at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 2

That's a best practice recommendation, and I would agree, although the separate reading and writing threads are rarely seen in practice. The answer to your question is that multiple threads can write at the same time, as long as you can unpick the resulting mess at the other end, taking buffer flushes into account, and that the read method is synchronized usually at the stack or kernel level so many threads can call it but only one will return for each piece of incoming data, whatever that may be (and you can't control its size from the sender).

ejpa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 3

Thanks boba5555,

Let me clarify that. I have am developing a client app. I have a single client socket connected to a server. Now I have serveral threads that will send messages to the server (write to the ouput buffer, concurrently and otherwise). These threads are supposed to wait for a reply from the server before it proceeds to its next task. I've tested this setup and it doesn't seem to work.

Here's my test setup:

1. Create a client socket

2. Create 3 threads which will write to the socket output buffer and wait for server reply

3. Start the 3 threads

Now here's how the program behaves:

1. The threads were able to send the messages "concurrently", although I'm sure this is syncrhonized.

2. The server replies got mixed up, i.e. thread 1 received reply for thread 2, thread 2 received reply for thread 3, etc.

So it is evident this setup will not work. What I'd like to ask is what setup is best for multiple threads writing to a single socket.

This is what I have in mind:

1. Create a client socket

2. Create a thread A which will pull outgoing messages from a queue, send messages to a server and wait for reply

3. Start thread A

4. Create 3 threads B which will write to the outgoing message queue and wait for a notification of server reply from thread A

5. Start B threads.

So B threads will write to the queue and wait for a notification of a server reply by thread A. Thread A sees an outgoing message. Send the message and waits for a reply. When it receives a reply, it notifies a thread B, then thread A continues sending the next message on the queue and so on.

This seems slow especially if server reply takes long. Is this the correct design?

By the way, the protocol i'm using is CIMD and UCP/EMI

Thanks in advance.

blood_aspa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 4
Do you want to send me your code? My e-mail is boba5555@gmail.com. If you send it, send as rar or zip.
boba5555a at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 5
please post your problem and ample code at: http://www.discussjava.com/wforum/
moskvitcha at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 6

It's now clear that you're trying to multiplex multiple logical channels over a single socket. In this case you will need (a) a logical channel identifier on every message, (b) single physical reading and writing threads, and (c) a system of say Queues to read/write the logical channel data to and from.

Wouldn't it be simpler to use multiple sockets?

ejpa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 7

But he can name threads and when send something to server it will have format

[thread_name]:[message]

and when server send response it will be

[thread_name]:[response]

and that will work.

@blood_asp:

But, if you know that after each message sent to server you have only one answer (only response) to same thread, then you can do something like this

synchronized sendMessage(Thread t){

sendToServer(t.getMessage());

t.setMessage(getFromServer()) /* this can be in.readline(). This line will wait until next input and that is server response*/

}

@ejp: Have I right or I made mistake?

boba5555a at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 8
As long as he writes logical channel numbers and message lengths along with every message, so every message can be unambiguously identified and extracted, this will work.Why would you bother? What is wrong with a socket per logical channel?
ejpa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 9
'What is wrong with a socket per logical channel?' - if this question is for me...Nothing wrong. That's ok. I just mentioned another solutions. One socket per one thread (channel) works fine.
boba5555a at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 10
The question was for the OP of course.
ejpa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 11

Hi boba5555,

Thanks, but I've already proven that the design I posted above won't work so I don't think it's necessarry to send my code. Your offer is appreciated. :)

I've also had in mind, naming the threads and packing the thread name together with the message, but I'm complying to CIMD/UCP protocol and the SMSC (server) has no provision for this.

Message was edited by:

blood_asp

blood_aspa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...
# 12

Thanks ejb, but just I've replied to boba5555 above, packing a thread name or id together with the message will not work since there is no provision for this in the CIMD/UCP protocol which I must adhere to. I have no control over the SMSC (server). I only want to develop a client app. Also, the reason I cannot use 1 socket per thread is because the SMSC only allows me one connection. Thanks again. :)

blood_aspa at 2007-7-14 21:31:39 > top of Java-index,Core,Core APIs...