[I am limited to Visual Studio 2010, and therefore, C# 4. async and await are not available to me.]
I'm working on network architecture for a project of mine, that sends packets of data over a network between a server and a client, but the client and server must continue running while waiting, so the code has to be non-blocking, so I thought to use the asynchronous methods. However, except for simple synchronous one-time IO, I don't know much about what to do, especially when using a NetworkStream. What I'm trying to do is:
1) Client connects to server
2) Server accepts connection
3) Server waits for data from client
4) Server processes data
5) Server responds to client
6) While connection is open, repeat from 3.
And I would like to use a NetworkStream to wrap the socket. But I am new to asynchronous I/O and i'm not really sure how to do this without blocking other parts of the server/client code when waiting for a response, especially with a NetworkStream. In my research I see examples that use something like this:
while(true){
socket.BeginAccept(new AsyncCallback(AcceptCallback), socket );
}
But it seems like that loop would still hold up the application. Can anyone give me some pointers (ha) on how exactly to do this? I haven't been able to find many examples that keep the connection open, only Client Connect -> Client Send -> Server Recieve -> Server Send -> Disconnect. I'm not asking for full code, just the general idea with a few snippets.
This is good examples that shows general idea of realisation async communication in C#
Asynchronous Client Socket Example: http://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx
Asynchronous Server Socket Example: http://msdn.microsoft.com/en-us/library/fx6588te%28v=vs.110%29.aspx
The code in server example binds to socket. And start to accept clients. When some client connects, the callback provided to BeginAccept called. In accept callback you can manage client socket and start to read or write. At the end of accept callback it signal allDone event and the main loop start to accept new client.
Take attention to:
this help to not waste cpu in loop.
Here is a very simple example of using async/await with a
NetworkStream
:SocketServer.cs:
Program.cs:
It's a very simple example, hosting both the server and client in the same process and accepting just one connection at a time. It's really just for illustration purposes. Real-world scenarios will no doubt include other features to suit their needs.
Here, I'm wrapping the
NetworkStream
s inStreamReader
s andStreamWriter
s. Note that you have to callFlush()
to ensure that the data is actually sent. For better control over the I/O, you can of course use theNetworkStream
directly. Just use theStream.ReadAsync()
method instead ofStreamReader.ReadLineAsync()
. Note also that in my example, writing is synchronous. You can make this asynchronous as well if you like, using the same basic technique as shown for reading.EDIT:
The OP indicates they are unable to use
async
/await
. Here is a version of the client which usesNetworkStream
and the old-styleBegin/EndXXX()
API (similar changes would be made to the server of course):Note that this code, even in spite of leaving out a bunch of exception-handling logic, is considerably longer, at least in part due to the fact that
TextReader
has no built-in asynchronous API, and so the processing of the input data is much more verbose here. Of course, this is for a simple line-based text exchange protocol. Other protocols may be more or less complex in terms of the data-unpacking aspects, but the underlying read and write elements of theNetworkStream
would be the same.