.Net Framework >> NetworkStream.BeginRead() wierdness

by 0to60 » Tue, 20 Sep 2005 22:41:30 GMT

I have a class that wraps a TcpClient object and manages all the async
reading of the socket. It works really nice, and I use it all over the
place. But there's this ONE INSTANCE where I create one of these things and
it WON'T read data. If I set a breakpoint in my EndRead callback, it never
goes off. NOTHING is different from anywhere else I use this class, its
just this one place.

Now, if I create a second constructor for my class that DOESN'T start off
the async reading process (basically, never calls BeginRead()), subsequent
Read()s will receive data. Additionally, if I do a loop like this:

while(!networkStream.DataAvailable)
Sleep(250);

networkStream.BeginRead(...)

Then the class works like it does everywhere else. Its like, in this one
instance (and this instance isn't any different than anywhere else I use
this class), I can't just do a BeginRead() and wait for data to come in. I
have to loop and check DataAvailable before calling BeginRead().

Any suggestions?



.Net Framework >> NetworkStream.BeginRead() wierdness

by Jason Craig » Wed, 05 Oct 2005 14:02:14 GMT


have the exact same problem:

Friend Sub ReadCallback(ByVal ar As IAsyncResult)

Try

Debug.WriteLine("Reading network stream...", Now.ToString)

Debug.WriteLine("Asynch read callback wait handle:" +
ar.AsyncWaitHandle.Handle.ToString, Now.ToString)

If DirectCast(DirectCast(ar.AsyncState, System.Array).GetValue(0),
NetworkStream).DataAvailable Then

Debug.WriteLine("Network stream has data.", Now.ToString)

Else

Debug.WriteLine("Network stream does not have any data.", Now.ToString)

End If

Debug.WriteLine("Ending read...", Now.ToString)

Debug.WriteLine(DirectCast(DirectCast(ar.AsyncState,
System.Array).GetValue(0), NetworkStream).EndRead(ar).ToString + " bytes
read from network stream.", Now.ToString)

Debug.WriteLine("Read has ended.", Now.ToString)

Catch ex As Exception

Debug.WriteLine(ex.Message)

End Try

End Sub

Public Function SendRequest(ByVal requestPdu As RocProtocolDataUnit) As
RocProtocolDataUnit

Dim ResponsePDU As RocProtocolDataUnit

Dim RetryCount As Int32

Dim StartTime As DateTime

Dim ReadBytes() As Byte

Dim ReadBuffer(247) As Byte

Dim ReadLength As Int32

Dim ReadAsyncResult As IAsyncResult

Dim MyNetworkStream As NetworkStream = _Connection.GetRocTcpClient.GetStream

StartTime = Now

Send:

Call MyNetworkStream.Write(requestPdu(True), 0, requestPdu(True).Length)

Debug.WriteLine("Attempting asynch read operation...", Now.ToString)

Dim ObjectArray(1) As Object

ObjectArray(0) = MyNetworkStream

ObjectArray(1) = ReadLength

ReadAsyncResult = MyNetworkStream.BeginRead(ReadBuffer, 0, 247, New
AsyncCallback(AddressOf Connection.ReadCallback), ObjectArray)

Debug.WriteLine("Got an asynch read result handle: " +
ReadAsyncResult.AsyncWaitHandle.Handle.ToString, Now.ToString)

Debug.WriteLine("Waiting for asynchronous operation to complete (or time
out).", Now.ToString)

Call ReadAsyncResult.AsyncWaitHandle.WaitOne(10000, True)

Debug.WriteLine("Finished waiting", Now.ToString)

If ReadAsyncResult.IsCompleted Then

Debug.WriteLine("Read completed", Now.ToString)

Else

Debug.WriteLine("Read uncomplete", Now.ToString)

End If

Debug.WriteLine("Dumping read buffer:", Now.ToString)

Debug.WriteLine(ConvertToHexByteString(ReadBuffer), Now.ToString)

Return ResponsePDU

End Function



Here is my debug output:

04/10/2005 11:58:43 PM: Attempting asynch read operation...

04/10/2005 11:58:43 PM: Got an asynch read result handle: 3604

04/10/2005 11:58:43 PM: Waiting for asynchronous operation to complete (or
time out).

04/10/2005 11:58:53 PM: Finished waiting

04/10/2005 11:58:53 PM: Read uncomplete

04/10/2005 11:58:53 PM: Dumping read buffer:

04/10/2005 11:58:53 PM:
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-0

.Net Framework >> NetworkStream.BeginRead() wierdness

by William Stacey [MVP] » Thu, 06 Oct 2005 00:07:05 GMT

Can you post a small client and server that demonstrates the issue?

--
William Stacey [MVP]

.Net Framework >> NetworkStream.BeginRead() wierdness

by Jason Craig » Thu, 06 Oct 2005 15:41:17 GMT

I have created a client and server for you:

ftp://craighome.dyndns.org/NetworkStreamBeginReadIssue.zip

The lack of examples and documentation of the NetworkStream.BeginRead method
has left me with many questions:

1.) Why is my ReadCallBack method invoked only when data is available on the
NetworkStream, it should be called right after the NetworkStream.BeginRead
method is called, regardless of any conditions.
2.) With slower connections (ie. CDMA Modems, Satelite Earth Stations, etc),
when data is written to the stream and an asynch read is performed without
waiting for the NetworkStream.DataAvailable property to return True,
ReadCallBack method is never invoked. Why does this happen?
2.) How do I prevent the network stream from being read if the WaitOne
method times out and then some data arrives?
3.) Why is the stream being read and the WaitOne method returning before I
call the EndRead method?
4.) Why does the NetworkStream.DataAvailable property return false, and yet
after I call the NetworkStream.EndRead method and that returns the number of
bytes read from the NetworkStream into the buffer.

.Net Framework >> NetworkStream.BeginRead() wierdness

by Helge Jensen » Thu, 06 Oct 2005 16:18:42 GMT


The callback is invoked after data is read from the stream and ready for
processing.


You shouldn't check DataAvailable when using AsyncIO, you should invoke
thestream.EndRead(asyncResult) to get the number of bytes actually read.


(you got 2.) two times :)


2(b) and 3 are related to your specific code, I haven't read that so I
can't answer them.


Because the DataAvailable is unrelated to the data you have read in your
async read.

example-code (not compiled):

public class ProcessStuff {
public readonly Stream Input;
public ProcessStuff(Stream s) { this.Input= s; }
public void readNext(int count) {
buffer = new byte[count];
Input.BeginRead(buffer, 0, buffer.Length,
new AsyncCallback(processInput), buffer);
}
protected void processInput(IAsyncResult r) {
int read;
try {
read = Input.EndRead(r);
} catch (Exception e) {
// notify someone of exception
// notify someone that you will stop reading
return;
}
if ( read == 0 ) { // Closed
// notify someone that you will stop reading
return;
}
byte[] mybuf = (byte[])r.AsyncState;

#if METHOD1
// Here i start read immideatly, this means that the order
// in which data arrive from the stream may not be maintained in
// the order of invocations of f.
// but there was hopefully a reason for using Aysync IO instead
// of sync.
readNext(somecount); // Keep reading data
f(mybuf, 0, read); // Do your stuff with the read data
#endif

#if METHOD2
// You may wish to
// 1) start f async (BeginInvoke)
// 2) wait for f to signal this thread that it has started and
// performed any nessesary synchronisation
// 3) start read-next after
// so that you can maintain the order of stream input as
// the order of f invocations, while still restarting reads
// as soon as possible
f.BeginInvoke(mybuf, 0 read);
somethingSignalledByf.WaitOne();
readnext(somecount);
#endif
}
}

--
Helge Jensen
mailto: XXXX@XXXXX.COM
sip: XXXX@XXXXX.COM
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Similar Threads

1. NetworkStream.BeginRead Blocking problem

2. NetworkStream BeginRead & callback invocation

BeginRead/EndRead doc implies the callback will execute and block on EndRead until data is available

"Your callback method should implement the EndRead method. When your application calls BeginRead, the system will use a separate thread to execute the specified callback method, and will block on EndRead until the provided NetworkStream reads data or throws an exception.

Testing this shows the callback is executed only when data is available; ie: if no data is received on the socket, the callback is not called. When EndRead is called within the callback, it returns immediately with the number of bytes read. The implication is also that EndRead will never block if the callback is only executed when data is available..

Same behavior was observed with .NET Compact Framework and regular .NET Framework (desktop)

Is this a known discrepancy in the doc and the real behavior is what we observed in our test

-
Thank
Patrick Gil
Motorola

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

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. NetworkStream / BeginRead / EndRead / Dataavailable: can't understand MSDN code sample

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

7. NetworkStreams impractical?, Buffering NetworkStreams, how?

8. networkStream.Write waits until networkstream.close

I have an issue where networkStream.Write doesn't perform its write
downstream from my client program until the network stream is closed.
 I then see the data that was sent appear on the other side.

I am sending a small amound of data and read where data wasn't sent
until the buffer reached a larger size.  However, there is a
TcpClient property call NoDelay that is suppose to eliminate this
delay.  Here is a snippet of my code below.  Can anyone think of a
reason why the networkStream.Write isn't performed until the
networkstream is closed?

        Dim tcpClient As New System.Net.Sockets.TcpClient()
        tcpClient.Connect("i set ip here", "and port here") 
//connection occurs as expected
        tcpClient.NoDelay() = True

        Dim networkStream As NetworkStream = tcpClient.GetStream()

        Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes("test")
        If NetworkStream.CanWrite And NetworkStream.CanRead Then
            ' Do a simple write.
            networkStream.Write(sendBytes, 0, sendBytes.Length)
            //this .write is returned but the data is not sent until a
networkstream.close is performed

*-----------------------*
        Posted at:
  www.GroupSrv.com
*-----------------------*