I want to use NetworkStream (or maybe Socket) to read/write TCP connections. I want to use non-blocking operations so that I don't have to deal with several threads, or deal with the issue of how to stop the program if some threads might be halted on blocking network operations.
The documentation of NetworkStream.Read implies it is non-blocking ("If no data is available for reading, the Read method returns 0"), so I guess I don't need async callbacks for reading... right?
But what about writing? Well, Microsoft has one of its usual low-quality tutorials on this subject, and they propose writing a cumbersome AsyncCallback method for every operation. What's the point of the code inside this callback?
client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), client); ... private static void SendCallback(IAsyncResult ar) { try { Socket client = (Socket)ar.AsyncState; int bytesSent = client.EndSend(ar); Console.WriteLine("Sent {0} bytes to server.", bytesSent); // Signal that all bytes have been sent. sendDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } The documentation of AsyncCallback says it's "a callback method that is called when the asynchronous operation completes". If the operation is completed already, why do we have to call Socket.EndSend(IAsyncResult)? Meanwhile, the documentation of NetworkStream.BeginWrite says "You must create a callback method that implements the AsyncCallback delegate and pass its name to the BeginWrite method. At the very minimum, your state parameter must contain the NetworkStream."
But why "must" I? Can't I just store the IAsyncResult somewhere...
_sendOp = client.BeginSend(message, 0, message.Length, SocketFlags.None, null, null); ...and periodically check whether it's finished?
if (_sendOp.IsCompleted) // start sending the next message in the queue (I know this implies polling, but it will be in a server that is expected to be active most of the time, and I'm planning some Thread.Sleeps when idle.)
Another issue. The messages I'm sending are broken up into a header array and a body array. Can I can issue two BeginWrites in a row?
IAsyncResult ar1 = _stream.BeginWrite(header, 0, header.Length, null, null); IAsyncResult ar2 = _stream.BeginWrite(msgBody, 0, msgBody.Length, null, null); Also, any opinions are welcome about whether to use Socket or NetworkStream.