CSharp/C# >> NetworkStream / BeginRead / EndRead / Dataavailable: can't understand MSDN code sample

by dc » Thu, 18 Sep 2003 23:43:12 GMT

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

CSharp/C# >> NetworkStream / BeginRead / EndRead / Dataavailable: can't understand MSDN code sample

by rich_blum » Fri, 19 Sep 2003 12:11:00 GMT



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

CSharp/C# >> NetworkStream / BeginRead / EndRead / Dataavailable: can't understand MSDN code sample

by dc » Mon, 22 Sep 2003 23:56:01 GMT

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

Best regards

DC

Similar Threads

1. Looking for good c# sample NetworkStream BeginRead/EndRead... - Microsoft .NET Framework

2. asynchronous programming model with BeginRead...EndRead

Hi!

Here I have a simple program that is using asynchronous programming.
As you know there are three styles of programming with Asynchronous 
Programming Model(APM) to deal with handling the end of the call in an 
asynchronous call: wait-until-done, polling and callback.
In this example I use the Rendezvous model Wait-Unit-Done Model.
When using this model(wait-unitl.done) I can't find point to use this when I 
still must wait being blocked until the asynchronous call is complete.
So you are blocked until complete when using  wait-until-done and you are 
blocked if you use the traditional synchronous model to read a file.
Does someone agree with me in this matter ?

static void Main()
{
      byte[] buffer = new byte[1000];
      string filename = "test.txt";
      FileStream fstrm = new FileStream(filename, FileMode.Open, 
FileAccess.Read,
         FileShare.Read, 1024, FileOptions.Asynchronous);
      IAsyncResult result = fstrm.BeginRead(buffer, 0, buffer.Length, null, 
null);
      int numBytes = fstrm.EndRead(result);
      fstrm.Close();
}

//Tony 


3. NetworkStream.DataAvailable - CSharp/C#

4. networkstream.beginread, socket error, no callback

Hi,

i was testing a network application that i've been working on which use .net
socket components. To read from a socket i use the networkstream beginread.
If the other side dies, beginread calls the callback delegate. Today i was
testing this in my old laptop (celeron 553MHz) and verify an interesting
thing. Callback is not called and this exception is captured by visual
studio.

An unhandled exception of type 'System.NullReferenceException' occurred in
system.dll

Additional information: Object reference not set to an instance of an
object.


Unhandled Exception: System.NullReferenceException: Object reference not set
to an instance of an object.
   at System.Net.OSSOCK.WSAGetOverlappedResult(IntPtr socketHandle, IntPtr
overlapped, UInt32& bytesTransferred, Boolean wait, IntPtr ignored)
   at System.Net.Sockets.OverlappedAsyncResult.CompletionPortCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)

Therefore, i assume there is a bug in beginread, usually hidden by the cpu
speed or so.

Who knows the why and suggest me the how?

Manuel


5. NetworkStream.BeginRead and Forms threading - CSharp/C#

6. C# 2.0 Exception Handling - Can't Understand MSDN Example

Hi There

I'm probably missing something fundamental here but I don't understand
the code in the OnThreadException routine, which is found in MSDN under
the topic: Application.ThreadException Event

I think the whole OnThreadException routine could be replaced with two
lines of code:

if (ShowThreadExceptionDialog(t.Exception) == DialogResult.Abort)
   Environment.Exit(0);

Why?  Because:
(1) FXCop complains about the MSDN example with CA1031 :
Microsoft.Design : Modify ... to catch a more specific exception than
'System.Object' or rethrow the exception.
(2) I don't understand why they even bother catching an exception as
they just give a totally useless message and terminate the application
anyways:

  try
  {
     MessageBox.Show("Fatal Error", "Fatal Error" ...
  }
  finally
  {
     Application.Exit();
  }

(3) Environment.Exit is more relevant for the project I am working on
as Application.Exit(0) only seems to end the blocking
Application.Run(new myMainForm()) line.  If there is code after the
Application.Run line it will still be executed. However I want to give
the application a "bullet in the head".

Thanks In Advance
Bill

7. NetworkStream EndRead SocketException OperationAborted - .Net Framework

8. NetworkStream DataAvailable, ReadByte() is slow

Good Day,
I had problems with speed of my data receiving function. My function i
accepting data from Network Stream.

In simplified version it looked:

//Receive Data from NetworkStream until char 13 arrive
private string ReceiveData(NetworkStream NS)
{
StringBuilder SB = new StringBuilder(512); 
while(true)
{
if(NS.DataAvailable)
{
byte OneByte = NS.ReadByte();
if(OneByte == 13)
break;
SB.Append((char)OneByte);
}
else
Thread.Sleep(10);
}
return SB.ToString();
}

I had big problems with speed of this function. I could accept onl
about 1000B/s on my Pocket PC. Problems are in "NS.DataAvailable" an
"OneByte = NS.ReadByte()".

Now I solved this problems by using Array of incoming bytes, but 
would like to ask You why is reading Byte by Byte so slow (I though
that it is only iteration of position in incoming data stream) . An
Why is testing "DataAvailable" so slow?

Thank Yo