Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- From: "Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Fri, 15 Sep 2006 12:01:20 -0700
"semedao" <semedao@xxxxxxxxxxxxxxxx> wrote in message
news:engiUTO2GHA.3516@xxxxxxxxxxxxxxxxxxxxxxx
[...]
I use the async result of the BeginReceive() WaitHandle.WaitOne() to block
on this thread until the bytes come , but , it does not block and return
as I described above.
When I debug this process of the both clients STEP by STEP , it's work
correctly and return those 5 bytes !
so , I can't find whay it's happen !
Disclaimer: while I've done plenty of Winsock programming, I haven't used
sockets in .NET yet. Still, I have what I think is a good guess as to
what's going on...
I believe that you misunderstand what the behavior of Begin/EndReceive is
(possibly because the documentation is misleading or incorrect). In
particular, assuming it works like the other async stuff in .NET, it does
NOT actually wait for data to be present on a non-blocking socket when you
wait on the AsyncResult or call EndReceive). All it does is cause the
particular call to Receive to happen on a different thread so that your own
thread can continue working. But in the other thread, it's like calling
Receive directly. There's no additional processing to check for data being
available.
So, in this case you've got a non-blocking socket, and the receive operation
completes essentially immediately since there's no data, and when you check
the results there is no data.
By stepping through (or probably any other delay), you allow time for the
data to get into the socket's receive buffer and become available to receive
in your thread.
In other words, using BeginReceive instead of Receive only makes sense if
you have a blocking socket. If you have a non-blocking socket, you need to
continue to use the normal i/o notification mechanism that you've chosen for
use with that socket.
IMHO, it's a little odd that EndReceive returns a value. If it were
completely analogous to the normal Winsock behavior, it'd throw (or return,
in the overload that returns an exception as a parameter) an exception when
no data is present (whatever the equivalent to WSAEWOULDBLOCK is...that is,
a SocketException where ErrorCode is set to WSAEWOULDBLOCK).
I realize that all of the above is in direct contradiction to the
documentation (in particular, the documentation for EndReceive reads in part
"The EndReceive method will block until data is available"). But given the
behavior you're seeing, and given how Winsock (the underlying Win32 API)
actually works, I think it's more likely that the documentation is wrong.
Making EndReceive blocking on a non-blocking socket would be non-trivial
(though not terribly difficult) and doing so would significantly reduce the
uniformity of the behavior of "End..." functions.
All that said, a quick look through the .NET Sockets documentation didn't
turn up anything that I recognized as a normal use of a non-blocking socket
other than Select. That is, you can get and set the Blocking property, but
I don't see any means other than calling Sockets.Select to find out when
it's reasonable to call Receive or Send on a socket. So to address the
above, the only solution I can see is to use the Select method to wait until
the socket becomes readable (and of course, depending on the .NET
implementation of Select, you may have to loop until you get the data you
want (or any data at all for that matter...in Winsock, calling select() does
not guarantee that when you get to the call to recv() you will actually get
any data back, even though most often that is the case).
If you are using the Blocking property, I assume that you actually know
about Select and any other mechanism that is similar, so hopefully there's
enough information here for you to get things working.
Pete
.
- Follow-Ups:
- References:
- BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- From: semedao
- Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- From: Daniel
- Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- From: semedao
- BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- Prev by Date: Re: VB to C#
- Next by Date: Re: Help With Using System.Text.Encoding To Download File
- Previous by thread: Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- Next by thread: Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode
- Index(es):
Relevant Pages
|