NetworkStream / BeginRead / EndRead / Dataavailable: can't understand MSDN code sample

D

DC

Hi,

I need to asynchronously read from a network (TCP) stream, and I am
having trouble with retrieving whole blocks; I get a break in the data
block every 1460 bytes which relates to network packet sizes I guess.

To get this fixed, I am trying to follow an example in the MSDN, which
pretty much resembles what I want to do. Since the code (I can't do
this in a static class for example) is not 100% what I need, I
certainly would like to understand what I am doing, but I guess I am
lacking some fundamentals of asynchronous programming since I simply
do not understand the code snippet. Here it is:


public static void myReadCallBack(IAsyncResult ar ){

NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
byte[] myReadBuffer = new byte[1024];
String myCompleteMessage = "";
int numberOfBytesRead;

numberOfBytesRead = myNetworkStream.EndRead(ar);
myCompleteMessage =
String.Concat(myCompleteMessage,
Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));

// message received may be larger than buffer size so loop through
until you have it all.
while(myNetworkStream.DataAvailable){

myNetworkStream.BeginRead(myReadBuffer, 0,
myReadBuffer.Length,
new
AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack),
myNetworkStream);

}

// Print out the received message to the console.
Console.WriteLine("You received the following message : " +
myCompleteMessage);
}


I wonder, how myCompleteMessage can ever add up to the complete
message, since it will be reinitialized at every callback, won't it?

If somebody can help me to understand this (what happens
"while(myNetworkStream.DataAvailable){...}") , I would be most
grateful.

Best regards

DC
 
R

Rich Blum

Hi,

I need to asynchronously read from a network (TCP) stream, and I am
having trouble with retrieving whole blocks; I get a break in the data
block every 1460 bytes which relates to network packet sizes I guess.


I wonder, how myCompleteMessage can ever add up to the complete
message, since it will be reinitialized at every callback, won't it?

If somebody can help me to understand this (what happens
"while(myNetworkStream.DataAvailable){...}") , I would be most
grateful.
DC -

This code snippet has problems at a couple of different levels. As
you point out, when you iterate through a method, you don't want to
reinitialize the buffer piecing the data together each time.
Initialize it at the global level and add each piece of data with each
iteration.

A second problem is the DataAvailable property. This value will
only be true if data is waiting in the socket buffer for you to read.
It doesn't know if more data is on the way and might be delayed. All
it knows is that no data is available at that moment.

The problem you must solve is how to let one end of the
communication know when it has received all of the data the other end
sent. There are three common methods used to do this:

1. If only one piece of data must be sent in the session, after the
sender sends the data it should close the socket. The receiving end
can loop on Reading data until an EndRead() method returns 0 bytes, it
then knows all of the data has been received and the connection has
been closed.

2. If multiple pieces of data must be sent in a single session, the
sender can send the size of each data element before the actual data
element. The receiving end can then read the data size value, and then
loop on Begin/End Read() methods until it knows all of the data bytes
have been received (using a counter that is not reinitialized on each
iteration).

3. Another method of sending multiple data elements is to use a
delimiter character to separate the data elements. The receiving end
reads data from the stream until it recognizes a delimiter character
(which should be something that is not normally seen in the data).
When it sees a delimiter character it knows all of the data has been
received.

I demonstrate each of these methods in my book. You can freely
download the example code from the Sybex web site to get a feel for
how to use each method. Hope this helps solve your problem.

Rich Blum - Author
"C# Network Programming" (Sybex)
http://www.sybex.com/sybexbooks.nsf/Booklist/4176
"Network Performance Open Source Toolkit" (Wiley)
http://www.wiley.com/WileyCDA/WileyTitle/productCd-0471433012.html
 
D

DC

Thanks a lot for your pointers, Rich. I more or less followed the
third method you propsed.

Best regards

DC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top