I am trying to conceptually work through a model for a client-server socket application I am writing in c# (both client and server). My server will need to handle many clients at once, and preferably multiple requests from a client at once. I have worked out a container for my communication where I will send a fixed length header at the beginning of each message which will contain (among other things) the length of the message. I have some experience with socket programming in c#, so I am comfortable using Asynchronous sockets.
The main thing I am having trouble with, conceptually, is I need both the client and server to be able to receive messages at any time. The client will establish a connection, and remain “logged in” (like an IM client), and it will need to both receive data at arbitrary times and make requests at arbitrary times. I had also wanted, as part of my protocol, to receive a response to each request made (be it from the server to client, or client to server).
I would like to be able to use a single socket if possible. I believe I could make this work using two sockets, one for making server->client requests and one for client->server requests, but I don’t want the extra complications of dealing with two ports/connections. However, using a single socket, I am not sure how to manage sending requests and getting responses when they could be interleaved.
I cannot find any examples of a similar server or client in my searching. Thanks to anyone who offers any ides.
If you’re using TCP, then you will necessarily have to have one socket per client on the server side, as well as the socket to listen for connections. For UDP you can do this all with one socket. Regardless, do the following for either your one UDP socket, or for each TCP client socket:
Have a
BeginReceivegoing at all times andBeginWritewhen you the necessary event occurs (ie the user presses a button or a message came in that you need to do something about).EDIT: In response to your comment, the way I’d handle it would be to include a request ID in your header. Whenever sending a request (from either end) include a unique value for that message. Use a
Dictionary<RequestId, RequestState>(with appropriate substitutions for the types) and see if an incoming message relates to a pre-existing request. Furthermore, you could specify that all IDs with the high bit set are requests originating at the client and IDs with the high bit cleared are from the server to avoid collisions:This is the system that AOL’s OSCAR protocol uses for (possibly slow) stateful requests.
EDIT2: Hm, ok… you really want to block on it? Something you could do is have a separate thread handle the
Send/Receivecalls. This thread would communicate with the main thread via a thread-safe “send message” queue and a similar “message received” psuedo-queue. The reason I call the latter a psuedo-queue is that you would want the ability to take messages out of order from the queue. The main thread would put a message on the send queue, then block on the receive queue. Each time the socket thread updates the receive queue, the main thread would wake up and check if the message it wants is there yet. If it is, it would take it (out of order) and finish the desired operation. If the message is not there yet, it’d just block on the queue again. When the operation is finally completed it’d just resume normal operation and get messages in order from the receive queue and process them or do whatever else it does.Does that make any sense? I’m sorry if it’s kinda confusing…