Hi

I've recently written a .NET client which communicated to a server via a
TcpClient class (from System.Net.Sockets).

One thing I noticed is my call to the GetStream().Read() method is not
blocking.

I've been through a few different sections in the MSDN help as well as a few
books and articles about the TcpClient class and have gotten some conflicting
information.

The information on the ReceiveTimeout property states it will set the
blocking on the NetworkStream.Read() method.

The documention on the NetworkStream.Read() method give the impression that
a call is non-block since it doesn't wait for data to become available before
returning.

I've looked at a number of samples of using the TcpClient class at various
sites and all appear to be written as if the Read method will block.

Does anyone know if there are specific conditions which may be affecting
this behaviour (i.e. additional properties or server / network factors)?

Thanks in advance

Al

Re: Blocking on NetworkStream.Read() by Peter

Peter
Wed Jul 11 16:05:57 CDT 2007

On Wed, 11 Jul 2007 03:46:06 -0700, AL <AL@discussions.microsoft.com>
wrote:

> I've recently written a .NET client which communicated to a server via a
> TcpClient class (from System.Net.Sockets).
>
> One thing I noticed is my call to the GetStream().Read() method is not
> blocking.

What do you mean that it "is not blocking"? If you mean that it is
returning immediately without reading any data, then I find that difficult
to believe. The only time this should happen is when the end of the
stream is reached, when it will return 0 for the bytes read.

If you mean that it is returning before it has read _all_ of the data that
is or will be sent on the stream, then yes. This is documented, by design
behavior. Stream.Read() is guaranteed only to return at least one byte,
as long as you have not reached the end of the stream.

http://msdn2.microsoft.com/en-us/library/system.io.filestream.read.aspx

Pete

Re: Blocking on NetworkStream.Read() by AL

AL
Thu Jul 12 08:52:04 CDT 2007

Hi

What is basically happening is if I do an immediate Read after I write to
the network stream. Read returns immediately with an empty buffer[]
regardless of the value I enter in the ReceiveTimeout property (10000 ms). If
I however introduce a delay between the write and read (either via a break
point or Thread.Sleep) the read operation returns me the data from the
network.

I have coded around this currently by swapping out the TcpClient for a
Socket class and executing Read on the Socket class. This now blocks until
the buffer has either started receiving data from the network or the timeout
expires.

Many thanks

AL


"Peter Duniho" wrote:

> On Wed, 11 Jul 2007 03:46:06 -0700, AL <AL@discussions.microsoft.com>
> wrote:
>
> > I've recently written a .NET client which communicated to a server via a
> > TcpClient class (from System.Net.Sockets).
> >
> > One thing I noticed is my call to the GetStream().Read() method is not
> > blocking.
>
> What do you mean that it "is not blocking"? If you mean that it is
> returning immediately without reading any data, then I find that difficult
> to believe. The only time this should happen is when the end of the
> stream is reached, when it will return 0 for the bytes read.
>
> If you mean that it is returning before it has read _all_ of the data that
> is or will be sent on the stream, then yes. This is documented, by design
> behavior. Stream.Read() is guaranteed only to return at least one byte,
> as long as you have not reached the end of the stream.
>
> http://msdn2.microsoft.com/en-us/library/system.io.filestream.read.aspx
>
> Pete
>

Re: Blocking on NetworkStream.Read() by Peter

Peter
Thu Jul 12 12:23:52 CDT 2007

On Thu, 12 Jul 2007 06:52:04 -0700, AL <AL@discussions.microsoft.com>
wrote:

> What is basically happening is if I do an immediate Read after I write to
> the network stream. Read returns immediately with an empty buffer[]
> regardless of the value I enter in the ReceiveTimeout property (10000
> ms). If
> I however introduce a delay between the write and read (either via a
> break
> point or Thread.Sleep) the read operation returns me the data from the
> network.
>
> I have coded around this currently by swapping out the TcpClient for a
> Socket class and executing Read on the Socket class. This now blocks
> until
> the buffer has either started receiving data from the network or the
> timeout
> expires.

Huh.

As much as I hate to say it (I'm always writing "it's not a bug in .NET"
because so many people are accusing .NET of having a bug when it's in
their own code :) ), I think maybe in this case you've found a bug in .NET.

It _seems_ to me that the NetworkStream() you get frmo TcpClient should be
exactly equivalent to the NetworkStream() you can get from a Socket. So
if the Socket works fine but the TcpClient does not when doing the same
exact thing, I'd say the TcpClient is broken somehow.

One minor point: you mention setting the ReceiveTimeout property. I don't
think that this should result in, or somehow prevent, the call to Read()
completing immediately. However, do keep in mind that if you set a
timeout for receiving, that if the timeout occurs, the socket is no longer
usable. I believe the same thing is true for TcpClient. If you want a
timeout, but want to be able to continue waiting for data on the socket
afterwards, you'll want to implement your own timeout logic (which would
require using asynchronous methods) rather than using the ReceiveTimeout
property.

Pete

Re: Blocking on NetworkStream.Read() by AL

AL
Fri Jul 13 02:46:07 CDT 2007


Hi

Thanks for the feedback. I would like to hope it's not a framework bug,
however am happy that I have gotten some more information.

Many thanks


"Peter Duniho" wrote:

> On Thu, 12 Jul 2007 06:52:04 -0700, AL <AL@discussions.microsoft.com>
> wrote:
>
> > What is basically happening is if I do an immediate Read after I write to
> > the network stream. Read returns immediately with an empty buffer[]
> > regardless of the value I enter in the ReceiveTimeout property (10000
> > ms). If
> > I however introduce a delay between the write and read (either via a
> > break
> > point or Thread.Sleep) the read operation returns me the data from the
> > network.
> >
> > I have coded around this currently by swapping out the TcpClient for a
> > Socket class and executing Read on the Socket class. This now blocks
> > until
> > the buffer has either started receiving data from the network or the
> > timeout
> > expires.
>
> Huh.
>
> As much as I hate to say it (I'm always writing "it's not a bug in .NET"
> because so many people are accusing .NET of having a bug when it's in
> their own code :) ), I think maybe in this case you've found a bug in .NET.
>
> It _seems_ to me that the NetworkStream() you get frmo TcpClient should be
> exactly equivalent to the NetworkStream() you can get from a Socket. So
> if the Socket works fine but the TcpClient does not when doing the same
> exact thing, I'd say the TcpClient is broken somehow.
>
> One minor point: you mention setting the ReceiveTimeout property. I don't
> think that this should result in, or somehow prevent, the call to Read()
> completing immediately. However, do keep in mind that if you set a
> timeout for receiving, that if the timeout occurs, the socket is no longer
> usable. I believe the same thing is true for TcpClient. If you want a
> timeout, but want to be able to continue waiting for data on the socket
> afterwards, you'll want to implement your own timeout logic (which would
> require using asynchronous methods) rather than using the ReceiveTimeout
> property.
>
> Pete
>