[Mono-devel-list] NetworkStream

Kornél Pál kornelpal at hotmail.com
Wed Jul 20 10:34:03 EDT 2005


Hi Károly,

> If I do not do the "While Not llogReadEverything" loop, it reads the data.
> Do not understand the reason why. :)

The problem is this line:

lintSize += tobjNetStream.Read(tbytBuffer, 0, tintFullSize)

As you are using the same buffer to read data you should increase the offset
everytime you read data.

The stream is sequential so the data you already have read is dropped by the
stream. (It it is buffered position is incremented and you have to seek back
if you want to access data you alread read.)

Furthermore you should decrement tintFullSize not to read more than you
want.

And you don't have to check DataAvailable because according to the
documentation it will block until some data is available. This doesn't means
that it will wait for all the data specified in size but it will return at
least one byte unless the connection is closed when it returns zero bytes.

You don't have to use ByRef if you want to access and object or modify an
array. You need it if you want to replace the object or the array with a
different one. I think a static buffer could be more efficient (don't have
to allocate new buffer everytime you call the funtion in the same method as
long as you use the same array) and you could simply use tintFullSize as a
number to be read. If you don't want this change you have to use ByRef as
you did before. And I think it is better to read the number of bytes read
than allways true.

You can ignore the above changes if you want.

I suggest you to use something like this:

Private Function ReadData(ByVal networkStream As NetworkStream, _
ByVal buffer As Byte(), ByVal size As Integer) As Integer
    Dim read As Integer
    Dim offset As Integer = 0

    Do
        read = networkStream.Read(buffer, offset, size)
        offset += read
        size -= read
    Loop Until size <= 0 OrElse read <= 0

    Return offset
End Function

Note that the above function does the same as NetworkStream.Read with the
exception that it will read "size" bytes anyway by waiting for data until
the connection is closed when it may return less bytes as no more is
available and will not arrive after the connection is closed.

Kornél

-----Original Message-----
From: Martin Hinks [mailto:mhinks at gmail.com]
Sent: Wednesday, July 20, 2005 10:59 AM
To: Arnhoffer Károly
Cc: mono-devel-list at lists.ximian.com
Subject: Re: [Mono-devel-list] NetworkStream


Hi Arnhoffer,

There are various things to try:

1.) Check that tIntFullSize is not 0 when the .Read line is called.
2.) Try this with a plain networkstream derived from a socket rather than
from a TcpClient
3.) If you are trying to read the entire buffer of length tintFullSize, is
it not possible that the server has not sent all the data when the read is
performed? ie. Just because DataAvailable is true does NOT mean that you may
be able to read ALL the data you are expecting from the stream, it might not
have arrived yet, and as you are expecting to be able to read it all it
might return 0 (I think it should block though, which is why it must work on
.NET)
4.) After some of the diagnoses above, file a bugzilla report.

Martin

On 7/20/05, Arnhoffer Károly <karnhoffer at ecron.hu> wrote:
> Hi,
>
> I have a server service created by Visual Studio .Net. It is using
> System.Net.Sockets.TcpClient.GetStream to get a stream to communicate
> on the network. When I run this service on a Windows machine (MS .NET
> framework) everything is fine, but when running on a Linux machine
> (SuSE 9.2, Mono 1.1.8 (from RPMs)) the service reads allways zeroes
> from the stream.
>
> Example:
>
>         Private Function ReadData(ByRef tobjNetStream As
> NetworkStream, ByRef tbytBuffer As Byte(), ByVal tintFullSize As
> Integer) As Boolean
>
>                 Dim lintSize As Integer = 0
>                 Dim llogReadEverything As Boolean
>                 Dim lintCounter As Integer
>
>                 ReDim tbytBuffer(tintFullSize - 1)
>
>                 While Not llogReadEverything
>                         While Not tobjNetStream.DataAvailable
>                                 Thread.CurrentThread.Sleep(50)
>                         End While
>
>                         lintSize += tobjNetStream.Read(tbytBuffer, 0,
> tintFullSize)
>                         If lintSize >= tintFullSize Then
>                                 llogReadEverything = True
>                         End If
>                 End While
>
>
>                 Return True
>         End Function
>
> A function like this gets zeroes from the stream when nonzero data was
> sent.
>
>
> Thanks!
> Arnhoffer Károly _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>


--
Martin Hinks
http://www.m-s-d.net
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list at lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list