Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Multiple threads writing and reading from single socket  RSS feed

 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'd like to ask if it's possible for multiple threads to write on a 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.
 
Ibrahim Yahia
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Raymond,

I ma really confused about your question, but let's to clarify something:

for reading and writing on the same socket concurrently there is no problem, what really will happenn is that, you first when connect to the server using Socket, you must get output and input streams from this Socket object for writing and reading, then you can make a thread that listening for incoming messages from the server by using input stream that you got it(while loop that reads using input stream), and make let's to say a separate method for send messages by using the output stream(you can call it from anywhere even from the reading thread itself). So the writing operation not conflict with the reading operation. Other point is that, you will control the sequence of messages between server and client by your code(for instance the client send a message to the server and the listening thread still wait for any messages to read, in server if the message is bla bla bla send to the client whatever so the client can read it using his listening thread).

but what make me confused is that, are you want to make multiple threads to write for server using the same client's output stream object.
 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Ibrahim,

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.

[ August 27, 2006: Message edited by: Raymond Ong ]
[ August 27, 2006: Message edited by: Raymond Ong ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The conventional approach is for each client thread to open a new client socket, send a request and read a response. On the server side the ServerSocket hands each request off to a new thread which reads the request and sends the response. Because the server handles each request on its own thread it's natural to send the response back to the client that is waiting for it. The kind of multiplexing errors you saw don't occur.

Here are a few lines from a server that works this way. It runs each new request on a thread from a pool (executor).

Can you try something like that?
 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Stan,

Actually the server implementation is not my problem. It's the client side.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So poke around a bit ... what does the server do if you open multiple sockets from the client? The code I showed is almost pseudo code for any self respecting server. It might behave perfectly. Or not.

If you send multiple messages over the same socket and look for responses to come back possibly out of order, you're into classic asnychronous mode. Messaging products like MQ-Series create a "correlation id" when they send the request, and put the same id on the response. That helps you know which requester wants each response. I think I have a bit on this HERE.
 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
So poke around a bit ... what does the server do if you open multiple sockets from the client? The code I showed is almost pseudo code for any self respecting server. It might behave perfectly. Or not.

If you send multiple messages over the same socket and look for responses to come back possibly out of order, you're into classic asnychronous mode. Messaging products like MQ-Series create a "correlation id" when they send the request, and put the same id on the response. That helps you know which requester wants each response. I think I have a bit on this HERE.


I've already done some tests As I've mentioned in my second post and the replies that the individual threads get aren't always the expected response which means that individual threads sending messages (synchronously) over the same socket will not work. Adding an ID for each message won't work also since there is no provision for this in the server using the CIMD/UCP protocol.

Thanks
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The client threads need to do the entire "send message, read response" sequence while holding onto a single shared lock object. i.e., what you're describing will work perfectly fine if you do



Assuming, of course, that the server is designed to handle multiple messages on a single client connection.

Make sense? I'm not sure why no one has explained this already.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I took "at the same time" to rule synchronizing like that out, but it oughtta help.

I also understood the trouble with "individual threads sending messages (synchronously) over the same socket ..." and wanted to try individual threads sending messages over different client sockets. If the server is built in a conventional manner it will accept many client threads connecting to the same server socket at the same time.
 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
The client threads need to do the entire "send message, read response" sequence while holding onto a single shared lock object. i.e., what you're describing will work perfectly fine if you do



Assuming, of course, that the server is designed to handle multiple messages on a single client connection.

Make sense? I'm not sure why no one has explained this already.


the code you posted is basically queueing, right? I just have to implement a time-out mechanism when reading replies from the server.

Thanks
 
Raymond Ong
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
I took "at the same time" to rule synchronizing like that out, but it oughtta help.

I also understood the trouble with "individual threads sending messages (synchronously) over the same socket ..." and wanted to try individual threads sending messages over different client sockets. If the server is built in a conventional manner it will accept many client threads connecting to the same server socket at the same time.


Yup. Thanks
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm, as you say I guess the effect of the synchronized block would be a lot like queuing, making threads wait for the monitor before they can send & receive, only it would not assure first in first out.

When you were multiplexing - sending multiple requests over one connection - did the responses come back in order? I thought from what you said they did not necessarily come back in order but maybe I misread. If they're out of order you're out of luck unless you can match the response to the request somehow. If they are LIFO you could maybe send a message and put the objec that wants the response in a queue of waiters.

Keep us posted how this works out!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!