compactframework >> NetworkStream.BeginRead Blocking problem

by TW9oaXQgR3VwdGE » Thu, 11 Nov 2004 12:28:04 GMT

Hi all,

I am trying to create CLient-Server based application. Talking of just
Client application, I want to read data from the server application. For
that
I created a socket and a new thread that reads all the time from the server.
However, the problem is when I close the socket (from client end), my data
reader thread (created above) does not close down. In turn it keeps waiting
for some message.

After bit of struggle I noted that somehow BeginRead calls back the method
after 1 minute. At that time my piece of code exits the thread. I want to
close the BeginRead operation as soon as I close the socket. You help will
be
appreciated. For that purpose I am presenting you with the code that I have
managed to write.


Public Delegate Sub DisplayInvoker(ByVal text As String)

Private Const IPADD As String = "192.168.11.2"
Private Const PORT As Integer = 5000

Private m_socketClient As TcpClient
Private m_data(1024) As Byte

#Region "Private Methods"
Private Sub connect()
Try
Dim ipAddObj As IPAddress = IPAddress.Parse(IPADD)
Dim ipEndPointObj As New IPEndPoint(ipAddObj, PORT)
Me.m_socketClient = New TcpClient(IPADD, PORT)
Me.btnSend.Enabled = True
Me.displayText("Connected to Host " + IPADD + " at Port " +
PORT.ToString())
Catch ex As Exception
Me.displayText("Socket connection failed")
Me.displayText("Reason: " + ex.Message)
Me.btnSend.Enabled = True
End Try
End Sub

Private Sub displayText(ByVal text As String)
If (text Is Nothing) Or (text = "") Then
Exit Sub
End If
Me.txtReceive.Text = Me.txtReceive.Text + vbCrLf + text
End Sub

Private Sub Send(ByVal text As String)
If Me.m_socketClient Is Nothing Then
Me.displayText("No socket connection available. Cannot send
text")
Exit Sub
End If
If (text Is Nothing) Or (text = "") Then
MessageBox.Show("No data to send")
Exit Sub
End If
Try
Dim bytes() As Byte = (New ASCIIEncoding).GetBytes(text)
Dim streamObj As Stream = Me.m_socketClient.GetStream()
streamObj.Write(bytes, 0, bytes.Length)
streamObj.Flush()
Me.displayText("Data Written: " + text)
Catch ex As Exception
Me.displayText("Sending FAILED: " + ex.Message)
End Try
End Sub

'This method is called to start reading
Private Sub BeginRead()
Try
Dim result As IAsyncResult =
Me.m_socketClient.GetStream.BeginRead(Me.m_data, 0, 1024, New
AsyncCallback(AddressOf Read), Nothing)
Catch ex As Exception
Me.displayText("Error at BeginRead: " + ex.Message)
End Try
End Sub

Private Sub Read(ByVal asyncResult As System.IAsyncResult)
Dim intCount As Int32 = 0
Try
intCount = Me.m_socketClient.GetStream.EndRead(asyncResult)
Me.displayText("Number of Bytes Received: " +
intCount.ToString())
If intCount < 1 Then
Me.displayText("Host connection closed")
Me.disconnect()
End If
Dim str As String = (New ASCIIEncoding).GetString(Me.m_data, 0,
intCount)
Dim result As IAsyncResult =
m_socketClient.GetStream.BeginRead(m_data, 0, 1024, New
AsyncCallback(AddressOf Read), Nothing)
Catch ex As Exception
Me.displayText("Error READING: " + ex.Message + " " + Now())
End Try
End Sub

Private Sub disconnect()
If Me.m_socketClient Is Nothing Then
Me.displayText("No socket connection")
Exit Sub
End If

Try
Me.displayText("Manually connection closed at " + Now())
Me.m_socketClient.Close()
Catch ex As Exception
Me.displayText("Socket Closing Failed: " + ex.Message)
End Try
End Sub
#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.connect()
Me.BeginRead()
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSend.Click
Me.Send(Me.txtSend.Text)
End Sub
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnClose.Click
Me.disconnect()
End Sub
Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnEnd.Click
Me.disconnect()
Me.Close()
Application.Exit()
End Sub
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnConnect.Click
Me.connect()
Me.BeginRead()
End Sub


Similar Threads

1. NetworkStream.BeginRead() wierdness - .Net Framework

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. Blocking on NetworkStream.Read() - .Net Framework

8. Can NetworkStream.Write() block?

myNetworkStream.Write(byte[], int offset, int size);

 From the MSDN documentation:
"
Remarks:
The Write method starts at the specified offset and sends size bytes 
from the contents of buffer to the network. The Write method blocks 
until the requested number of bytes is sent or a SocketException is 
thrown. If you receive a SocketException, use the 
SocketException.ErrorCode property to obtain the specific error code, 
and refer to the Windows Sockets version 2 API error code documentation 
in MSDN for a detailed description of the error.
"

It says the call blocks until the bytes are sent but aren't the bytes 
just queued to the write buffer until the OS feels like sending them 
over the wire?  Therefore doesn't the call always return pretty much 
immediately anyway?

Thanks.