Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode



Hello again,

I didn't read all of Peters reply but he did mention the delay fixing it.
Also you said 'no' to my comment that your 'losing data.

Well if when you debug you receive 5 bytes and when you don't debug you
don't recive 5 bytes....haven't you lost data?

the fatc you reminded me you are using async sockets makes me think your new
to it.

I have written commerical software using async sockets in .net 2.0 and when
i was learning i had the exact same problem,.

What i didn't know at the time was a few key things:

1) data will never go out of order
2) you will never lose bytes
3) you may receive all your data in one stream call

So say you sent 10 bytes, then 5 bytes then 5 more bytes

Your endreceive may return : 20bytes.......it may return 10, then 5 then
5...(as in when there is a delay due to debugging), or it may return 15 then
5.

When i had the sam problem as you it was because i was doing the end reieve,
reading the received bytes, then breaking out of my loop and waiting for
more data on the socket. That point where i broke i lost remining data. So
only when the correct amount came through in one call did i get it all.
Sound slike your issue.

So make sure you read very byte that comes in. If your buffer is 1024 bytes
and you receive 1024 bytes, read them all. And be sure to send the size
expected along too. So you know how much to read of each object sent. And
remmber you need to handle overlap.

For example if your buffer is 1024 bytes in size and you have an object of
1023 bytes and you alway send the first 4 bytes before any send as the size
of data to come, then the 1024th byte, and then the 1st, 2nd and 3rd bytes
of the next receive will be that 4byts size of the next data block coming
in.

If what i say above confuses then re-read sockets, your understanding is
flawes. As i say Peter may have already explained this to you.



"Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx> wrote in message
news:12glu4bl9qt6d47@xxxxxxxxxxxxxxxxxxxxx
"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



.



Relevant Pages

  • Re: Socket.Disconnect Method
    ... Although the exception list in the MSDN documentation ... Windows XP SP2. ... An error occurred when attempting to access the socket. ... use the SocketException.ErrorCode property to obtain the specific error code. ...
    (microsoft.public.vsnet.general)
  • Re: BeginReceive return zero length buffer when run ,and work correctly when use step by step debug
    ... (possibly because the documentation is misleading or incorrect). ... So, in this case you've got a non-blocking socket, and the receive operation ... If you are using the Blocking property, I assume that you actually know ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: [Q] How to Forumulate HTTP request using fsockopen() / fputs()
    ... I can find no documentation ... Frame HTTP Request Command. ... Write the command to socket. ... access have FTP access. ...
    (comp.lang.php)
  • Re: Nonblocking send. Is it a BUG in Windows Socket API?
    ... WinSock documentation. ... sendfunction must not return WSAENOBUFS error ... > regardless of the socket is blocking or nonblocking. ...
    (microsoft.public.win32.programmer.networks)
  • Re: Socket.Disconnect Method
    ... According to the documentation for this method, ... An error occurred when attempting to access the socket. ... It looks to me like the underlying error code could have been: ... This method ends the connection and sets the Connected ...
    (microsoft.public.vsnet.general)

Quantcast