By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,491 Members | 3,273 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,491 IT Pros & Developers. It's quick & easy.

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

P: n/a
Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i'ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don't want to use sync calls because the rest of the
session is async also , so I only want to makethe async - sinc like forthis
part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?
Sep 15 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Bit confused by what you are saying is the problem but can you calrify.

If you send an object to the other client, it is not always getting there.
But if you debug, it does? Is the problem that you are 'losing' bytes?
"semedao" <se*****@community.nospamwrote in message
news:ei**************@TK2MSFTNGP02.phx.gbl...
Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i'ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data
received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don't want to use sync calls because the rest of
the session is async also , so I only want to makethe async - sinc like
forthis part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?


Sep 15 '06 #2

P: n/a
No,
I have some send recv conversation between 2 clients
the mode is async sockets.
when I come to some location in the code that I want to recv 5 bytes , the
recv return before the bytes received , the length of the EndRecv() is 0
(zero) ,
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 !
"Daniel" <Da*****@vestryonline.comwrote in message
news:ub**************@TK2MSFTNGP05.phx.gbl...
Bit confused by what you are saying is the problem but can you calrify.

If you send an object to the other client, it is not always getting there.
But if you debug, it does? Is the problem that you are 'losing' bytes?
"semedao" <se*****@community.nospamwrote in message
news:ei**************@TK2MSFTNGP02.phx.gbl...
>Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i'ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data
received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don't want to use sync calls because the rest of
the session is async also , so I only want to makethe async - sinc like
forthis part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?



Sep 15 '06 #3

P: n/a
"semedao" <se*****@community.nospamwrote in message
news:en**************@TK2MSFTNGP06.phx.gbl...
[...]
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
Sep 15 '06 #4

P: n/a
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" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"semedao" <se*****@community.nospamwrote in message
news:en**************@TK2MSFTNGP06.phx.gbl...
>[...]
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

Sep 15 '06 #5

P: n/a
"Daniel" <Da*****@vestryonline.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
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?
Not necessarily. All we know is that he doesn't receive the data when he
expected to. Since he has no loop around his receive attempt, he definitely
will fail to read the data if it's not read the first time through. But the
data remains on the socket, until such time as it IS read or the socket is
closed. It's entirely possible that his code does eventually read the data,
preventing it from being lost.

I'd say if he says he doesn't lose data, we should take his word for it, at
least for the moment. :)

In addition...
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.
All true. However, the thing that many programmers miss (and which you
didn't mention) is that you may not even receive 10 bytes or 5 bytes or any
given number of bytes for any given call to receive.

In your example, the sender sends 20 bytes. The receiver may in fact wind
up receiving 1 byte at a time, 20 times, and the code must be prepared to
deal with this. In reality, the extreme cases almost never happen (eg
getting just one byte at a time) but the API specification doesn't guarantee
anything better than that, and if your code isn't handling that degenerate
case, it likely also doesn't handle the more likely cases as well.

With a stream-oriented socket (eg TCP), there are no message boundaries.
The way the data is grouped during the send has nothing to do with the way
the data is grouped during the receive.

Now, as it happens, we don't really know whether the original poster is
using a stream-oriented socket. I didn't see anything in his post or code
that implies TCP (or similar protocol). If he's using UDP, all of the above
isn't relevant and there's a whole different set of considerations (ie, one
receive always returns exactly what one send sent, but you may receive the
same datagram more than once, not at all, or out of order from the other
datagrams).

The real issue here appears to be what "blocking" and "non-blocking" mean
with respect to the .NET implementation of sockets. I suspect that even
though the documentation says otherwise, the EndReceive method only blocks
until the receive is completed when a blocking socket is used (and of
course, as you point out, for a TCP socket "complete" does not necessary
mean "the buffer has been filled"...it just means *some* data has been
received).

Pete
Sep 15 '06 #6

P: n/a
Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??
firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the expected
buffer length , the app is in infinite loop in case when the return of
endrecv is zero.
so , how can I handle it ?

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Daniel" <Da*****@vestryonline.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
>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?

Not necessarily. All we know is that he doesn't receive the data when he
expected to. Since he has no loop around his receive attempt, he
definitely will fail to read the data if it's not read the first time
through. But the data remains on the socket, until such time as it IS
read or the socket is closed. It's entirely possible that his code does
eventually read the data, preventing it from being lost.

I'd say if he says he doesn't lose data, we should take his word for it,
at least for the moment. :)

In addition...
>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.

All true. However, the thing that many programmers miss (and which you
didn't mention) is that you may not even receive 10 bytes or 5 bytes or
any given number of bytes for any given call to receive.

In your example, the sender sends 20 bytes. The receiver may in fact wind
up receiving 1 byte at a time, 20 times, and the code must be prepared to
deal with this. In reality, the extreme cases almost never happen (eg
getting just one byte at a time) but the API specification doesn't
guarantee anything better than that, and if your code isn't handling that
degenerate case, it likely also doesn't handle the more likely cases as
well.

With a stream-oriented socket (eg TCP), there are no message boundaries.
The way the data is grouped during the send has nothing to do with the way
the data is grouped during the receive.

Now, as it happens, we don't really know whether the original poster is
using a stream-oriented socket. I didn't see anything in his post or code
that implies TCP (or similar protocol). If he's using UDP, all of the
above isn't relevant and there's a whole different set of considerations
(ie, one receive always returns exactly what one send sent, but you may
receive the same datagram more than once, not at all, or out of order from
the other datagrams).

The real issue here appears to be what "blocking" and "non-blocking" mean
with respect to the .NET implementation of sockets. I suspect that even
though the documentation says otherwise, the EndReceive method only blocks
until the receive is completed when a blocking socket is used (and of
course, as you point out, for a TCP socket "complete" does not necessary
mean "the buffer has been filled"...it just means *some* data has been
received).

Pete

Sep 15 '06 #7

P: n/a
"semedao" <se*****@community.nospamwrote in message
news:OC**************@TK2MSFTNGP02.phx.gbl...
Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??
At what point is it missing? Do you ever try to read from the socket again
after getting a 0 return value from EndReceive and throwing an exception? I
think that's an important clarification.
firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the
expected buffer length , the app is in infinite loop in case when the
return of endrecv is zero.
so , how can I handle it ?
oopsie on my part. I didn't notice you had the whole non-blocking scenario
wrapped in a do/while loop. I think your loop is fine (except that it
didn't include the blocking case), and should in fact keep control within
the loop until you've read sufficient data (as long as you don't throw an
exception, so the first step is to take that out as a response to receiving
a 0 return value).

Secondly, I would forget (at least for the moment) using Begin/EndReceive.
I think it's an unnecessary distraction, especially since you want your code
to block anyway. Use a regular Receive. With a non-blocking socket, you'll
want to also call Socket.Select to block your thread until data is available
on the socket. Since I haven't used .NET sockets, I don't really know
whether you're using the Begin/EndReceive functions correctly, but they seem
to me to be unneeded here, since you don't intend for your thread to
continue doing some other work after calling BeginReceive.

Third, I finally noticed a bug in your call to Receive, in which you fail to
update the buffer offset. I don't think this would cause the issue you're
asking about, but it's a serious problem.
Here's how I'd try to write it (note of course that not having used sockets
in .NET, I can't guarantee this is perfectly correct :) ):

public static byte[] Receive(Socket openSocket, int length)
{
byte[] buffer = new byte[length];
int totalreceive = 0;

do
{
int lastreceive;

/*
* For non-blocking sockets, the Socket.Select method will block
* the thread until there is actually data to be read from the
socket.
*
* If you want to get really picky, check to make sure your socket
* is still in the socklistRead list before trying to read from it.
* Since it's the only one that was in there to begin with, it still
* should be and even if it's not the worst that can happen is we
* loop back around and try again.
*/
if (!openSocket.Blocking)
{
ArrayList socklistRead = new ArrayList();

socklistRead.Add(openSocket);
Socket.Select(socklistRead, null, null, -1);
}

/* Be prepared for an exception */
try
{
/*
* For blocking socket, this will block the thread until
* data is available. For a non-blocking socket, we hope
* that the data is still there after returning from
* Socket.Select, but it's no big deal if it's not (we'll
* get a WSAEWOULDBLOCK error and go back to try again).
*/
lastreceive = openSocket.Receive(buffer, totalreceive, length,
SocketFlags.None);

/*
* Sockets will return zero if the socket is
* closed and we've already read all the data on the socket
*/
if (lastreceive == 0)
{
throw new Exception("Socket was closed");
}
}
catch (SocketException exc)
{
/*
* WSAEWOULDBLOCK is a non-fatal error...we just need to
* go back and try again.
*/
if (exc.ErrorCode != WSAEWOULDBLOCK)
{
throw;
}
lastreceive = 0;
}
catch
{
throw;
}

/*
* At this point, we've received valid data, and it's been
* put into the buffer. Update our byte counter to reflect
* that.
*/
totalreceive += lastreceive;
length -= lastreceive;
} while (length 0);
}

By the way, there is a Socket.Receive overload that takes an "out ErrorCode"
parameter. The docs claim that even this method returns an exception in the
case of a Winsock error, but I suspect that in reality the function returns
SOCKET_ERROR (-1) and sets the output parameter (this would be consistent
with how Winsock itself works). I didn't bother to try it to see, since
other exceptions can still happen anyway, but if it's true that you can
detect WSAEWOULDBLOCK that way instead, it might be nicer to use that
instead of having to use a try/catch block within the loop. Instead of:

try
{...}
catch (SocketException...)
{...}
catch
{...}

You'd have something like this:

lastreceive = openSocket.Receive(..., err);
if (lastreceive == SOCKET_ERROR)
{
if (err != WSAEWOULDBLOCK)
{
throw new SocketException(err);
}

lastreceive = 0;
}
else if (lastreceive == 0)
{
throw new Exception("Socket was closed");
}

Note the extensive use of ellipsis' to denote code I didn't want to bother
typing out. :)

Anyway, I hope this helps. I'm making the (possibly incorrect) assumption
that the .NET version of sockets doesn't stray too far from the underlying
functionality. I essentially translated what I do know to be correct for
Winsock generally into the means and methods available in .NET. With some
luck, it'll be exactly what you need. :)

Pete
Sep 16 '06 #8

P: n/a
Hey Sem

Since i have implemented what you are doing successfully and did in fact get
it right that you are 'losing' bytes i will continue to try and help.

the reason i believe you are losing data is the exact reason that i was when
i first attempted this.

Ok imagine this, you send a total of 800 bytes, and your buffer is 500 bytes
in size (500 for arguments sake to keep numbers easy)

Your async socket listens and receives 500 bytes (your total buffer size
with still 300 to come), you read the full buffer and then finish. Now the
next 300 comes through and so you receive 300 bytes.

So your second receive is a 500 byte buffer with only 300 byes of data in
it.

So when you hit the 300th byte of that 500 check your code and see if at
this point you stop reading, as after all you have your data, and break. If
so you just lost 200 bytes. Sure that 200 bytes may be empty but it might
not. If another send was done at the other end it may have been joined on
the end. and your break just ignored it.

So this is what you must remember:

1) Send 4 bytes containing the ength of the data being sent
2) receiveing end, read first 4 bytes and store size of data to come
3) read that many bytes and use the end of those bytes not as a point to
break and say end of transmission but end of that object being received and
now...
4) ....now the next 4 bytes check for size again and so on ans so on

So to clarfiy further. Imagine sending an object of 1024 bytes in size. We
would do this

a) create 4 bytes containing the length of the data being sent, the number
1024
b) send the 4 bytes
c) send the data
d) receive and
1)first receive check first 4 bytes to get size expected
2) read that many bytes
3) on reading that many bytes check next 4 bytes received for expected
size of next data comin thorugh
4) if expected size now is 0 then no more to come, go back to active
waiting state
5) if not 0 then read as usual and so on
Does that make sense?

"semedao" <se*****@community.nospamwrote in message
news:OC**************@TK2MSFTNGP02.phx.gbl...
Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??
firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the
expected buffer length , the app is in infinite loop in case when the
return of endrecv is zero.
so , how can I handle it ?

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
>"Daniel" <Da*****@vestryonline.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
>>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?

Not necessarily. All we know is that he doesn't receive the data when he
expected to. Since he has no loop around his receive attempt, he
definitely will fail to read the data if it's not read the first time
through. But the data remains on the socket, until such time as it IS
read or the socket is closed. It's entirely possible that his code does
eventually read the data, preventing it from being lost.

I'd say if he says he doesn't lose data, we should take his word for it,
at least for the moment. :)

In addition...
>>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.

All true. However, the thing that many programmers miss (and which you
didn't mention) is that you may not even receive 10 bytes or 5 bytes or
any given number of bytes for any given call to receive.

In your example, the sender sends 20 bytes. The receiver may in fact
wind up receiving 1 byte at a time, 20 times, and the code must be
prepared to deal with this. In reality, the extreme cases almost never
happen (eg getting just one byte at a time) but the API specification
doesn't guarantee anything better than that, and if your code isn't
handling that degenerate case, it likely also doesn't handle the more
likely cases as well.

With a stream-oriented socket (eg TCP), there are no message boundaries.
The way the data is grouped during the send has nothing to do with the
way the data is grouped during the receive.

Now, as it happens, we don't really know whether the original poster is
using a stream-oriented socket. I didn't see anything in his post or
code that implies TCP (or similar protocol). If he's using UDP, all of
the above isn't relevant and there's a whole different set of
considerations (ie, one receive always returns exactly what one send
sent, but you may receive the same datagram more than once, not at all,
or out of order from the other datagrams).

The real issue here appears to be what "blocking" and "non-blocking" mean
with respect to the .NET implementation of sockets. I suspect that even
though the documentation says otherwise, the EndReceive method only
blocks until the receive is completed when a blocking socket is used (and
of course, as you point out, for a TCP socket "complete" does not
necessary mean "the buffer has been filled"...it just means *some* data
has been received).

Pete


Sep 16 '06 #9

P: n/a
Not sure what is wrong with your code, but here is some that should work for
you.

public delegate void GetBytesDelegate(byte[] buf, Exception ex);
public static void GetBytes(Socket s, int length, GetBytesDelegate
callback)
{
if (length < 1)
throw new ArgumentOutOfRangeException("length");

byte[] buffer = new byte[length];
int bytesRead = 0;

AsyncCallback cb = null;
cb = delegate(IAsyncResult ar)
{
try
{
int read = s.EndReceive(ar);
if (read == 0)
{
callback(null, null); // Peer closed send.
return;
}

bytesRead += read;

if (bytesRead == length)
callback(buffer, null); // Done.
else // Else, need more data.
s.BeginReceive(buffer, bytesRead, length -
bytesRead, SocketFlags.None, cb, null);
}
catch (Exception ex)
{
callback(buffer, ex);
}
};

s.BeginReceive(buffer, bytesRead, length - bytesRead,
SocketFlags.None, cb, null);
}

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:ei**************@TK2MSFTNGP02.phx.gbl...
| Hi , I am using asyc sockets p2p connection between 2 clients.
| when I debug step by step the both sides , i'ts work ok.
| when I run it , in somepoint (same location in the code)
| when I want to receive 5 bytes buffer , I call the BeginReceive and then
| wait on AsyncWaitHandle.WaitOne()
| but it is signald imidiatly , and the next call to EndReceive return zero
| bytes length , also the buffer is empty.
| here is the code:
| public static byte[] Receive(Socket OpenSocket, int length)
|
| {
|
| byte[] buffer = new byte[length];
|
| int totalreceive = 0;
|
| int _lastReceive = 0;
|
| if (OpenSocket.Blocking)
|
| totalreceive = OpenSocket.Receive(buffer);
|
| else
|
| {
|
| IAsyncResult ar;
|
| do
|
| {
|
| //in this point the OpenSocket.Available == 0 !
|
| ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
| null);
|
| ar.AsyncWaitHandle.WaitOne(); // something "signald it before data
received?
|
| _lastReceive = OpenSocket.EndReceive(ar);
|
| if (_lastReceive == 0) // happen when run the code , doeas not happen if
| step by step slowly!
|
| {
|
| buffer = null;
|
| throw new Exception("No data receive");
|
| }
|
| totalreceive += _lastReceive;
|
| } while (totalreceive < length);
|
| }
|
| return buffer;
|
| }
|
| what is my problem ? I don't want to use sync calls because the rest of
the
| session is async also , so I only want to makethe async - sinc like
forthis
| part ofthe code , also , when in the debug mode I change the
| OpenSocket.Blocking to True - cause it to call sync receive instead of
| beginrecv , also return with zero length buffer
|
|
|
| any ideas ?
|
|
Sep 16 '06 #10

P: n/a
Hi Daniel,
this is exaclty what I already did!
but , when I want to read the first 5 btes (my header , 1 more byte for
"command" ) , I receive the zero length !
it's happen in the first read , before I start the loop of
header->packet->header->packet...

"Daniel" <Da*****@vestryonline.comwrote in message
news:Ok**************@TK2MSFTNGP05.phx.gbl...
Hey Sem

Since i have implemented what you are doing successfully and did in fact
get it right that you are 'losing' bytes i will continue to try and help.

the reason i believe you are losing data is the exact reason that i was
when i first attempted this.

Ok imagine this, you send a total of 800 bytes, and your buffer is 500
bytes in size (500 for arguments sake to keep numbers easy)

Your async socket listens and receives 500 bytes (your total buffer size
with still 300 to come), you read the full buffer and then finish. Now the
next 300 comes through and so you receive 300 bytes.

So your second receive is a 500 byte buffer with only 300 byes of data in
it.

So when you hit the 300th byte of that 500 check your code and see if at
this point you stop reading, as after all you have your data, and break.
If so you just lost 200 bytes. Sure that 200 bytes may be empty but it
might not. If another send was done at the other end it may have been
joined on the end. and your break just ignored it.

So this is what you must remember:

1) Send 4 bytes containing the ength of the data being sent
2) receiveing end, read first 4 bytes and store size of data to come
3) read that many bytes and use the end of those bytes not as a point to
break and say end of transmission but end of that object being received
and now...
4) ....now the next 4 bytes check for size again and so on ans so on

So to clarfiy further. Imagine sending an object of 1024 bytes in size. We
would do this

a) create 4 bytes containing the length of the data being sent, the number
1024
b) send the 4 bytes
c) send the data
d) receive and
1)first receive check first 4 bytes to get size expected
2) read that many bytes
3) on reading that many bytes check next 4 bytes received for expected
size of next data comin thorugh
4) if expected size now is 0 then no more to come, go back to active
waiting state
5) if not 0 then read as usual and so on
Does that make sense?

"semedao" <se*****@community.nospamwrote in message
news:OC**************@TK2MSFTNGP02.phx.gbl...
>Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??
firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the
expected buffer length , the app is in infinite loop in case when the
return of endrecv is zero.
so , how can I handle it ?

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
>>"Daniel" <Da*****@vestryonline.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl.. .
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?

Not necessarily. All we know is that he doesn't receive the data when
he expected to. Since he has no loop around his receive attempt, he
definitely will fail to read the data if it's not read the first time
through. But the data remains on the socket, until such time as it IS
read or the socket is closed. It's entirely possible that his code does
eventually read the data, preventing it from being lost.

I'd say if he says he doesn't lose data, we should take his word for it,
at least for the moment. :)

In addition...

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.

All true. However, the thing that many programmers miss (and which you
didn't mention) is that you may not even receive 10 bytes or 5 bytes or
any given number of bytes for any given call to receive.

In your example, the sender sends 20 bytes. The receiver may in fact
wind up receiving 1 byte at a time, 20 times, and the code must be
prepared to deal with this. In reality, the extreme cases almost never
happen (eg getting just one byte at a time) but the API specification
doesn't guarantee anything better than that, and if your code isn't
handling that degenerate case, it likely also doesn't handle the more
likely cases as well.

With a stream-oriented socket (eg TCP), there are no message boundaries.
The way the data is grouped during the send has nothing to do with the
way the data is grouped during the receive.

Now, as it happens, we don't really know whether the original poster is
using a stream-oriented socket. I didn't see anything in his post or
code that implies TCP (or similar protocol). If he's using UDP, all of
the above isn't relevant and there's a whole different set of
considerations (ie, one receive always returns exactly what one send
sent, but you may receive the same datagram more than once, not at all,
or out of order from the other datagrams).

The real issue here appears to be what "blocking" and "non-blocking"
mean with respect to the .NET implementation of sockets. I suspect that
even though the documentation says otherwise, the EndReceive method only
blocks until the receive is completed when a blocking socket is used
(and of course, as you point out, for a TCP socket "complete" does not
necessary mean "the buffer has been filled"...it just means *some* data
has been received).

Pete



Sep 16 '06 #11

P: n/a
Hi peter , when I used the sync methods it throw exception related to mixed
block-unblock sockets...
only for this reason I made those helper methods
If I use the loop and don't break when recv zero length - I enter inside
un-finished loop.

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12************@corp.supernews.com...
"semedao" <se*****@community.nospamwrote in message
news:OC**************@TK2MSFTNGP02.phx.gbl...
>Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??

At what point is it missing? Do you ever try to read from the socket
again after getting a 0 return value from EndReceive and throwing an
exception? I think that's an important clarification.
>firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the
expected buffer length , the app is in infinite loop in case when the
return of endrecv is zero.
so , how can I handle it ?

oopsie on my part. I didn't notice you had the whole non-blocking
scenario wrapped in a do/while loop. I think your loop is fine (except
that it didn't include the blocking case), and should in fact keep control
within the loop until you've read sufficient data (as long as you don't
throw an exception, so the first step is to take that out as a response to
receiving a 0 return value).

Secondly, I would forget (at least for the moment) using Begin/EndReceive.
I think it's an unnecessary distraction, especially since you want your
code to block anyway. Use a regular Receive. With a non-blocking socket,
you'll want to also call Socket.Select to block your thread until data is
available on the socket. Since I haven't used .NET sockets, I don't
really know whether you're using the Begin/EndReceive functions correctly,
but they seem to me to be unneeded here, since you don't intend for your
thread to continue doing some other work after calling BeginReceive.

Third, I finally noticed a bug in your call to Receive, in which you fail
to update the buffer offset. I don't think this would cause the issue
you're asking about, but it's a serious problem.
Here's how I'd try to write it (note of course that not having used
sockets in .NET, I can't guarantee this is perfectly correct :) ):

public static byte[] Receive(Socket openSocket, int length)
{
byte[] buffer = new byte[length];
int totalreceive = 0;

do
{
int lastreceive;

/*
* For non-blocking sockets, the Socket.Select method will block
* the thread until there is actually data to be read from the
socket.
*
* If you want to get really picky, check to make sure your socket
* is still in the socklistRead list before trying to read from it.
* Since it's the only one that was in there to begin with, it
still
* should be and even if it's not the worst that can happen is we
* loop back around and try again.
*/
if (!openSocket.Blocking)
{
ArrayList socklistRead = new ArrayList();

socklistRead.Add(openSocket);
Socket.Select(socklistRead, null, null, -1);
}

/* Be prepared for an exception */
try
{
/*
* For blocking socket, this will block the thread until
* data is available. For a non-blocking socket, we hope
* that the data is still there after returning from
* Socket.Select, but it's no big deal if it's not (we'll
* get a WSAEWOULDBLOCK error and go back to try again).
*/
lastreceive = openSocket.Receive(buffer, totalreceive, length,
SocketFlags.None);

/*
* Sockets will return zero if the socket is
* closed and we've already read all the data on the socket
*/
if (lastreceive == 0)
{
throw new Exception("Socket was closed");
}
}
catch (SocketException exc)
{
/*
* WSAEWOULDBLOCK is a non-fatal error...we just need to
* go back and try again.
*/
if (exc.ErrorCode != WSAEWOULDBLOCK)
{
throw;
}
lastreceive = 0;
}
catch
{
throw;
}

/*
* At this point, we've received valid data, and it's been
* put into the buffer. Update our byte counter to reflect
* that.
*/
totalreceive += lastreceive;
length -= lastreceive;
} while (length 0);
}

By the way, there is a Socket.Receive overload that takes an "out
ErrorCode" parameter. The docs claim that even this method returns an
exception in the case of a Winsock error, but I suspect that in reality
the function returns SOCKET_ERROR (-1) and sets the output parameter (this
would be consistent with how Winsock itself works). I didn't bother to
try it to see, since other exceptions can still happen anyway, but if it's
true that you can detect WSAEWOULDBLOCK that way instead, it might be
nicer to use that instead of having to use a try/catch block within the
loop. Instead of:

try
{...}
catch (SocketException...)
{...}
catch
{...}

You'd have something like this:

lastreceive = openSocket.Receive(..., err);
if (lastreceive == SOCKET_ERROR)
{
if (err != WSAEWOULDBLOCK)
{
throw new SocketException(err);
}

lastreceive = 0;
}
else if (lastreceive == 0)
{
throw new Exception("Socket was closed");
}

Note the extensive use of ellipsis' to denote code I didn't want to bother
typing out. :)

Anyway, I hope this helps. I'm making the (possibly incorrect) assumption
that the .NET version of sockets doesn't stray too far from the underlying
functionality. I essentially translated what I do know to be correct for
Winsock generally into the means and methods available in .NET. With some
luck, it'll be exactly what you need. :)

Pete

Sep 16 '06 #12

P: n/a
I am a little confused. Your first read is receiving 0 bytes? Well the
eventual read that does receive some bytes, i assume you do eventually
receive something, that will be your header. I think you are going to need
to post some code for this.
"semedao" <se*****@community.nospamwrote in message
news:OB**************@TK2MSFTNGP04.phx.gbl...
Hi Daniel,
this is exaclty what I already did!
but , when I want to read the first 5 btes (my header , 1 more byte for
"command" ) , I receive the zero length !
it's happen in the first read , before I start the loop of
header->packet->header->packet...

"Daniel" <Da*****@vestryonline.comwrote in message
news:Ok**************@TK2MSFTNGP05.phx.gbl...
>Hey Sem

Since i have implemented what you are doing successfully and did in fact
get it right that you are 'losing' bytes i will continue to try and help.

the reason i believe you are losing data is the exact reason that i was
when i first attempted this.

Ok imagine this, you send a total of 800 bytes, and your buffer is 500
bytes in size (500 for arguments sake to keep numbers easy)

Your async socket listens and receives 500 bytes (your total buffer size
with still 300 to come), you read the full buffer and then finish. Now
the next 300 comes through and so you receive 300 bytes.

So your second receive is a 500 byte buffer with only 300 byes of data in
it.

So when you hit the 300th byte of that 500 check your code and see if at
this point you stop reading, as after all you have your data, and break.
If so you just lost 200 bytes. Sure that 200 bytes may be empty but it
might not. If another send was done at the other end it may have been
joined on the end. and your break just ignored it.

So this is what you must remember:

1) Send 4 bytes containing the ength of the data being sent
2) receiveing end, read first 4 bytes and store size of data to come
3) read that many bytes and use the end of those bytes not as a point to
break and say end of transmission but end of that object being received
and now...
4) ....now the next 4 bytes check for size again and so on ans so on

So to clarfiy further. Imagine sending an object of 1024 bytes in size.
We would do this

a) create 4 bytes containing the length of the data being sent, the
number 1024
b) send the 4 bytes
c) send the data
d) receive and
1)first receive check first 4 bytes to get size expected
2) read that many bytes
3) on reading that many bytes check next 4 bytes received for
expected size of next data comin thorugh
4) if expected size now is 0 then no more to come, go back to active
waiting state
5) if not 0 then read as usual and so on
Does that make sense?

"semedao" <se*****@community.nospamwrote in message
news:OC**************@TK2MSFTNGP02.phx.gbl...
>>Hi , I take back my words about missing data... :))
ok ok , the data is missing , but , help me understand
why ??
firsy - yes , I am using TCP
now , If I made loop around the "beginRecv until it will return the
expected buffer length , the app is in infinite loop in case when the
return of endrecv is zero.
so , how can I handle it ?

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Daniel" <Da*****@vestryonline.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl. ..
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?

Not necessarily. All we know is that he doesn't receive the data when
he expected to. Since he has no loop around his receive attempt, he
definitely will fail to read the data if it's not read the first time
through. But the data remains on the socket, until such time as it IS
read or the socket is closed. It's entirely possible that his code
does eventually read the data, preventing it from being lost.

I'd say if he says he doesn't lose data, we should take his word for
it, at least for the moment. :)

In addition...

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.

All true. However, the thing that many programmers miss (and which you
didn't mention) is that you may not even receive 10 bytes or 5 bytes or
any given number of bytes for any given call to receive.

In your example, the sender sends 20 bytes. The receiver may in fact
wind up receiving 1 byte at a time, 20 times, and the code must be
prepared to deal with this. In reality, the extreme cases almost never
happen (eg getting just one byte at a time) but the API specification
doesn't guarantee anything better than that, and if your code isn't
handling that degenerate case, it likely also doesn't handle the more
likely cases as well.

With a stream-oriented socket (eg TCP), there are no message
boundaries. The way the data is grouped during the send has nothing to
do with the way the data is grouped during the receive.

Now, as it happens, we don't really know whether the original poster is
using a stream-oriented socket. I didn't see anything in his post or
code that implies TCP (or similar protocol). If he's using UDP, all of
the above isn't relevant and there's a whole different set of
considerations (ie, one receive always returns exactly what one send
sent, but you may receive the same datagram more than once, not at all,
or out of order from the other datagrams).

The real issue here appears to be what "blocking" and "non-blocking"
mean with respect to the .NET implementation of sockets. I suspect
that even though the documentation says otherwise, the EndReceive
method only blocks until the receive is completed when a blocking
socket is used (and of course, as you point out, for a TCP socket
"complete" does not necessary mean "the buffer has been filled"...it
just means *some* data has been received).

Pete



Sep 16 '06 #13

P: n/a
Sounds like peer socket is closing send before you receive. Did you try my
code?

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:OB**************@TK2MSFTNGP04.phx.gbl...
| Hi Daniel,
| this is exaclty what I already did!
| but , when I want to read the first 5 btes (my header , 1 more byte for
| "command" ) , I receive the zero length !
| it's happen in the first read , before I start the loop of
| header->packet->header->packet...
|
| "Daniel" <Da*****@vestryonline.comwrote in message
| news:Ok**************@TK2MSFTNGP05.phx.gbl...
| Hey Sem
| >
| Since i have implemented what you are doing successfully and did in fact
| get it right that you are 'losing' bytes i will continue to try and
help.
| >
| the reason i believe you are losing data is the exact reason that i was
| when i first attempted this.
| >
| Ok imagine this, you send a total of 800 bytes, and your buffer is 500
| bytes in size (500 for arguments sake to keep numbers easy)
| >
| Your async socket listens and receives 500 bytes (your total buffer size
| with still 300 to come), you read the full buffer and then finish. Now
the
| next 300 comes through and so you receive 300 bytes.
| >
| So your second receive is a 500 byte buffer with only 300 byes of data
in
| it.
| >
| So when you hit the 300th byte of that 500 check your code and see if at
| this point you stop reading, as after all you have your data, and break.
| If so you just lost 200 bytes. Sure that 200 bytes may be empty but it
| might not. If another send was done at the other end it may have been
| joined on the end. and your break just ignored it.
| >
| So this is what you must remember:
| >
| 1) Send 4 bytes containing the ength of the data being sent
| 2) receiveing end, read first 4 bytes and store size of data to come
| 3) read that many bytes and use the end of those bytes not as a point to
| break and say end of transmission but end of that object being received
| and now...
| 4) ....now the next 4 bytes check for size again and so on ans so on
| >
| So to clarfiy further. Imagine sending an object of 1024 bytes in size.
We
| would do this
| >
| a) create 4 bytes containing the length of the data being sent, the
number
| 1024
| b) send the 4 bytes
| c) send the data
| d) receive and
| 1)first receive check first 4 bytes to get size expected
| 2) read that many bytes
| 3) on reading that many bytes check next 4 bytes received for
expected
| size of next data comin thorugh
| 4) if expected size now is 0 then no more to come, go back to active
| waiting state
| 5) if not 0 then read as usual and so on
| >
| >
| Does that make sense?
| >
| >
| >
| >
| >
| "semedao" <se*****@community.nospamwrote in message
| news:OC**************@TK2MSFTNGP02.phx.gbl...
| >Hi , I take back my words about missing data... :))
| >ok ok , the data is missing , but , help me understand
| >why ??
| >firsy - yes , I am using TCP
| >now , If I made loop around the "beginRecv until it will return the
| >expected buffer length , the app is in infinite loop in case when the
| >return of endrecv is zero.
| >so , how can I handle it ?
| >>
| >"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
| >news:12*************@corp.supernews.com...
| >>"Daniel" <Da*****@vestryonline.comwrote in message
| >>news:%2****************@TK2MSFTNGP03.phx.gbl.. .
| >>>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?
| >>>
| >>Not necessarily. All we know is that he doesn't receive the data when
| >>he expected to. Since he has no loop around his receive attempt, he
| >>definitely will fail to read the data if it's not read the first time
| >>through. But the data remains on the socket, until such time as it IS
| >>read or the socket is closed. It's entirely possible that his code
does
| >>eventually read the data, preventing it from being lost.
| >>>
| >>I'd say if he says he doesn't lose data, we should take his word for
it,
| >>at least for the moment. :)
| >>>
| >>In addition...
| >>>
| >>>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.
| >>>
| >>All true. However, the thing that many programmers miss (and which
you
| >>didn't mention) is that you may not even receive 10 bytes or 5 bytes
or
| >>any given number of bytes for any given call to receive.
| >>>
| >>In your example, the sender sends 20 bytes. The receiver may in fact
| >>wind up receiving 1 byte at a time, 20 times, and the code must be
| >>prepared to deal with this. In reality, the extreme cases almost
never
| >>happen (eg getting just one byte at a time) but the API specification
| >>doesn't guarantee anything better than that, and if your code isn't
| >>handling that degenerate case, it likely also doesn't handle the more
| >>likely cases as well.
| >>>
| >>With a stream-oriented socket (eg TCP), there are no message
boundaries.
| >>The way the data is grouped during the send has nothing to do with the
| >>way the data is grouped during the receive.
| >>>
| >>Now, as it happens, we don't really know whether the original poster
is
| >>using a stream-oriented socket. I didn't see anything in his post or
| >>code that implies TCP (or similar protocol). If he's using UDP, all
of
| >>the above isn't relevant and there's a whole different set of
| >>considerations (ie, one receive always returns exactly what one send
| >>sent, but you may receive the same datagram more than once, not at
all,
| >>or out of order from the other datagrams).
| >>>
| >>The real issue here appears to be what "blocking" and "non-blocking"
| >>mean with respect to the .NET implementation of sockets. I suspect
that
| >>even though the documentation says otherwise, the EndReceive method
only
| >>blocks until the receive is completed when a blocking socket is used
| >>(and of course, as you point out, for a TCP socket "complete" does not
| >>necessary mean "the buffer has been filled"...it just means *some*
data
| >>has been received).
| >>>
| >>Pete
| >>>
| >>
| >>
| >
| >
|
|
Sep 16 '06 #14

P: n/a
Yeah i agree with Will, that would send a 0 bytes.

"William Stacey [MVP]" <wi************@gmail.comwrote in message
news:eL**************@TK2MSFTNGP06.phx.gbl...
Sounds like peer socket is closing send before you receive. Did you try
my
code?

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:OB**************@TK2MSFTNGP04.phx.gbl...
| Hi Daniel,
| this is exaclty what I already did!
| but , when I want to read the first 5 btes (my header , 1 more byte for
| "command" ) , I receive the zero length !
| it's happen in the first read , before I start the loop of
| header->packet->header->packet...
|
| "Daniel" <Da*****@vestryonline.comwrote in message
| news:Ok**************@TK2MSFTNGP05.phx.gbl...
| Hey Sem
| >
| Since i have implemented what you are doing successfully and did in
fact
| get it right that you are 'losing' bytes i will continue to try and
help.
| >
| the reason i believe you are losing data is the exact reason that i
was
| when i first attempted this.
| >
| Ok imagine this, you send a total of 800 bytes, and your buffer is 500
| bytes in size (500 for arguments sake to keep numbers easy)
| >
| Your async socket listens and receives 500 bytes (your total buffer
size
| with still 300 to come), you read the full buffer and then finish. Now
the
| next 300 comes through and so you receive 300 bytes.
| >
| So your second receive is a 500 byte buffer with only 300 byes of data
in
| it.
| >
| So when you hit the 300th byte of that 500 check your code and see if
at
| this point you stop reading, as after all you have your data, and
break.
| If so you just lost 200 bytes. Sure that 200 bytes may be empty but it
| might not. If another send was done at the other end it may have been
| joined on the end. and your break just ignored it.
| >
| So this is what you must remember:
| >
| 1) Send 4 bytes containing the ength of the data being sent
| 2) receiveing end, read first 4 bytes and store size of data to come
| 3) read that many bytes and use the end of those bytes not as a point
to
| break and say end of transmission but end of that object being
received
| and now...
| 4) ....now the next 4 bytes check for size again and so on ans so on
| >
| So to clarfiy further. Imagine sending an object of 1024 bytes in
size.
We
| would do this
| >
| a) create 4 bytes containing the length of the data being sent, the
number
| 1024
| b) send the 4 bytes
| c) send the data
| d) receive and
| 1)first receive check first 4 bytes to get size expected
| 2) read that many bytes
| 3) on reading that many bytes check next 4 bytes received for
expected
| size of next data comin thorugh
| 4) if expected size now is 0 then no more to come, go back to
active
| waiting state
| 5) if not 0 then read as usual and so on
| >
| >
| Does that make sense?
| >
| >
| >
| >
| >
| "semedao" <se*****@community.nospamwrote in message
| news:OC**************@TK2MSFTNGP02.phx.gbl...
| >Hi , I take back my words about missing data... :))
| >ok ok , the data is missing , but , help me understand
| >why ??
| >firsy - yes , I am using TCP
| >now , If I made loop around the "beginRecv until it will return the
| >expected buffer length , the app is in infinite loop in case when the
| >return of endrecv is zero.
| >so , how can I handle it ?
| >>
| >"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
| >news:12*************@corp.supernews.com...
| >>"Daniel" <Da*****@vestryonline.comwrote in message
| >>news:%2****************@TK2MSFTNGP03.phx.gbl.. .
| >>>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?
| >>>
| >>Not necessarily. All we know is that he doesn't receive the data
when
| >>he expected to. Since he has no loop around his receive attempt, he
| >>definitely will fail to read the data if it's not read the first
time
| >>through. But the data remains on the socket, until such time as it
IS
| >>read or the socket is closed. It's entirely possible that his code
does
| >>eventually read the data, preventing it from being lost.
| >>>
| >>I'd say if he says he doesn't lose data, we should take his word for
it,
| >>at least for the moment. :)
| >>>
| >>In addition...
| >>>
| >>>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.
| >>>
| >>All true. However, the thing that many programmers miss (and which
you
| >>didn't mention) is that you may not even receive 10 bytes or 5 bytes
or
| >>any given number of bytes for any given call to receive.
| >>>
| >>In your example, the sender sends 20 bytes. The receiver may in
fact
| >>wind up receiving 1 byte at a time, 20 times, and the code must be
| >>prepared to deal with this. In reality, the extreme cases almost
never
| >>happen (eg getting just one byte at a time) but the API
specification
| >>doesn't guarantee anything better than that, and if your code isn't
| >>handling that degenerate case, it likely also doesn't handle the
more
| >>likely cases as well.
| >>>
| >>With a stream-oriented socket (eg TCP), there are no message
boundaries.
| >>The way the data is grouped during the send has nothing to do with
the
| >>way the data is grouped during the receive.
| >>>
| >>Now, as it happens, we don't really know whether the original poster
is
| >>using a stream-oriented socket. I didn't see anything in his post
or
| >>code that implies TCP (or similar protocol). If he's using UDP, all
of
| >>the above isn't relevant and there's a whole different set of
| >>considerations (ie, one receive always returns exactly what one send
| >>sent, but you may receive the same datagram more than once, not at
all,
| >>or out of order from the other datagrams).
| >>>
| >>The real issue here appears to be what "blocking" and "non-blocking"
| >>mean with respect to the .NET implementation of sockets. I suspect
that
| >>even though the documentation says otherwise, the EndReceive method
only
| >>blocks until the receive is completed when a blocking socket is used
| >>(and of course, as you point out, for a TCP socket "complete" does
not
| >>necessary mean "the buffer has been filled"...it just means *some*
data
| >>has been received).
| >>>
| >>Pete
| >>>
| >>
| >>
| >
| >
|
|


Sep 16 '06 #15

P: n/a
"semedao" <se*****@community.nospamwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
Hi peter , when I used the sync methods it throw exception related to
mixed block-unblock sockets...
I don't know what that means. You should be more specific. What exception
exactly is thrown? What does the error say? If it's a SocketException,
what is the SocketErrorCode? On what line of code does it occur?

The code that I posted is precisely how one would do things using regular
Winsock. If .NET has somehow disabled calling the standard Receive method
on non-blocking sockets, it has seriously broken how Windows sockets work.
It also begs the question as to why the method Select is provided in .NET,
since the primary purpose of Select is to block the thread until the call to
Receive is likely to return data on a non-blocking socket.

Absent any clarification, the way I read your reply is that the code I
posted is throwing the exceptions you're talking about. But the code I
posted doesn't use a non-blocking socket in a way that would be invalid
using regular Winsock (nor a blocking socket, for that matter). So without
you being specific, your reply is very puzzling.
only for this reason I made those helper methods
I understand the general idea of making helper methods to try to make a
non-blocking socket behave like a blocking socket. But again, I didn't post
anything that should be an invalid use of a socket, so your reply saying
that exceptions are thrown is confusing, especially when you don't say
exactly what is happening.
If I use the loop and don't break when recv zero length - I enter inside
un-finished loop.
My code throws an exception if the call to Receive returns a zero length. I
don't see how the loop could continue past that point. As the comments in
my code specifically say, when Receive returns the value zero, that means
that the connection has been closed and you've read all the data that has
been sent.

If you have designed your protocol correctly, you will never get a zero
length read when you actually expect to get more data unless some error has
occurred, thus the thrown exception in the code I posted.

In any case, at this point I'm out of ideas. If you can't be more specific
in your description of what about the code I posted doesn't work, I can't
offer anything more. Sorry.

Pete
Sep 16 '06 #16

P: n/a
friends !
You right - the sender close the socket (for other bug reasons that I still
need to understand why happen onlywhen running and not step by step... :) )
and that's what cause the WaitOne to signald and then the EndReceive return
zero , but what I didn't understand is why it's does not throwme a
SocketException ???
if the exception was throw - it was so much easy to debug!
more then that , I can continue with my loop until... forever - very
confused
Any case thank you all very much
"Daniel" <Da*****@vestryonline.comwrote in message
news:Oz**************@TK2MSFTNGP03.phx.gbl...
Yeah i agree with Will, that would send a 0 bytes.

"William Stacey [MVP]" <wi************@gmail.comwrote in message
news:eL**************@TK2MSFTNGP06.phx.gbl...
>Sounds like peer socket is closing send before you receive. Did you try
my
code?

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:OB**************@TK2MSFTNGP04.phx.gbl...
| Hi Daniel,
| this is exaclty what I already did!
| but , when I want to read the first 5 btes (my header , 1 more byte for
| "command" ) , I receive the zero length !
| it's happen in the first read , before I start the loop of
| header->packet->header->packet...
|
| "Daniel" <Da*****@vestryonline.comwrote in message
| news:Ok**************@TK2MSFTNGP05.phx.gbl...
| Hey Sem
| >
| Since i have implemented what you are doing successfully and did in
fact
| get it right that you are 'losing' bytes i will continue to try and
help.
| >
| the reason i believe you are losing data is the exact reason that i
was
| when i first attempted this.
| >
| Ok imagine this, you send a total of 800 bytes, and your buffer is
500
| bytes in size (500 for arguments sake to keep numbers easy)
| >
| Your async socket listens and receives 500 bytes (your total buffer
size
| with still 300 to come), you read the full buffer and then finish.
Now
the
| next 300 comes through and so you receive 300 bytes.
| >
| So your second receive is a 500 byte buffer with only 300 byes of
data
in
| it.
| >
| So when you hit the 300th byte of that 500 check your code and see if
at
| this point you stop reading, as after all you have your data, and
break.
| If so you just lost 200 bytes. Sure that 200 bytes may be empty but
it
| might not. If another send was done at the other end it may have been
| joined on the end. and your break just ignored it.
| >
| So this is what you must remember:
| >
| 1) Send 4 bytes containing the ength of the data being sent
| 2) receiveing end, read first 4 bytes and store size of data to come
| 3) read that many bytes and use the end of those bytes not as a point
to
| break and say end of transmission but end of that object being
received
| and now...
| 4) ....now the next 4 bytes check for size again and so on ans so on
| >
| So to clarfiy further. Imagine sending an object of 1024 bytes in
size.
We
| would do this
| >
| a) create 4 bytes containing the length of the data being sent, the
number
| 1024
| b) send the 4 bytes
| c) send the data
| d) receive and
| 1)first receive check first 4 bytes to get size expected
| 2) read that many bytes
| 3) on reading that many bytes check next 4 bytes received for
expected
| size of next data comin thorugh
| 4) if expected size now is 0 then no more to come, go back to
active
| waiting state
| 5) if not 0 then read as usual and so on
| >
| >
| Does that make sense?
| >
| >
| >
| >
| >
| "semedao" <se*****@community.nospamwrote in message
| news:OC**************@TK2MSFTNGP02.phx.gbl...
| >Hi , I take back my words about missing data... :))
| >ok ok , the data is missing , but , help me understand
| >why ??
| >firsy - yes , I am using TCP
| >now , If I made loop around the "beginRecv until it will return the
| >expected buffer length , the app is in infinite loop in case when
the
| >return of endrecv is zero.
| >so , how can I handle it ?
| >>
| >"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
| >news:12*************@corp.supernews.com...
| >>"Daniel" <Da*****@vestryonline.comwrote in message
| >>news:%2****************@TK2MSFTNGP03.phx.gbl.. .
| >>>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?
| >>>
| >>Not necessarily. All we know is that he doesn't receive the data
when
| >>he expected to. Since he has no loop around his receive attempt,
he
| >>definitely will fail to read the data if it's not read the first
time
| >>through. But the data remains on the socket, until such time as it
IS
| >>read or the socket is closed. It's entirely possible that his code
does
| >>eventually read the data, preventing it from being lost.
| >>>
| >>I'd say if he says he doesn't lose data, we should take his word
for
it,
| >>at least for the moment. :)
| >>>
| >>In addition...
| >>>
| >>>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.
| >>>
| >>All true. However, the thing that many programmers miss (and which
you
| >>didn't mention) is that you may not even receive 10 bytes or 5
bytes
or
| >>any given number of bytes for any given call to receive.
| >>>
| >>In your example, the sender sends 20 bytes. The receiver may in
fact
| >>wind up receiving 1 byte at a time, 20 times, and the code must be
| >>prepared to deal with this. In reality, the extreme cases almost
never
| >>happen (eg getting just one byte at a time) but the API
specification
| >>doesn't guarantee anything better than that, and if your code isn't
| >>handling that degenerate case, it likely also doesn't handle the
more
| >>likely cases as well.
| >>>
| >>With a stream-oriented socket (eg TCP), there are no message
boundaries.
| >>The way the data is grouped during the send has nothing to do with
the
| >>way the data is grouped during the receive.
| >>>
| >>Now, as it happens, we don't really know whether the original
poster
is
| >>using a stream-oriented socket. I didn't see anything in his post
or
| >>code that implies TCP (or similar protocol). If he's using UDP,
all
of
| >>the above isn't relevant and there's a whole different set of
| >>considerations (ie, one receive always returns exactly what one
send
| >>sent, but you may receive the same datagram more than once, not at
all,
| >>or out of order from the other datagrams).
| >>>
| >>The real issue here appears to be what "blocking" and
"non-blocking"
| >>mean with respect to the .NET implementation of sockets. I suspect
that
| >>even though the documentation says otherwise, the EndReceive method
only
| >>blocks until the receive is completed when a blocking socket is
used
| >>(and of course, as you point out, for a TCP socket "complete" does
not
| >>necessary mean "the buffer has been filled"...it just means *some*
data
| >>has been received).
| >>>
| >>Pete
| >>>
| >>
| >>
| >
| >
|
|



Sep 16 '06 #17

P: n/a
"semedao" <se*****@community.nospamwrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
friends !
You right - the sender close the socket (for other bug reasons that I
still need to understand why happen onlywhen running and not step by
step... :) )
and that's what cause the WaitOne to signald and then the EndReceive
return zero , but what I didn't understand is why it's does not throwme a
SocketException ???
As I wrote a couple of times already, when a connection is closed, the
defined behavior is for the receive to return 0 bytes. If you had actually
used the code I posted, that code itself would have thrown an exception,
telling you that the socket connection had been closed.
if the exception was throw - it was so much easy to debug!
Well, IMHO it's a lot easier to debug when you have read and understood the
API documentation. Even the .NET version of sockets documents in several
places the fact that Receive will return 0 as the bytes received when the
connection has been closed.
more then that , I can continue with my loop until... forever - very
confused
Receive will just keep returning 0 bytes, so you make no progress. Thus the
endless loop.
Any case thank you all very much
You're welcome.

Pete
Sep 16 '06 #18

P: n/a
Shutdown.Send is not an exception, it is expected behavior (at some point) -
same with using socket directly. You must always check for 0 return.

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
| friends !
| You right - the sender close the socket (for other bug reasons that I
still
| need to understand why happen onlywhen running and not step by step...
:) )
| and that's what cause the WaitOne to signald and then the EndReceive
return
| zero , but what I didn't understand is why it's does not throwme a
| SocketException ???
| if the exception was throw - it was so much easy to debug!
| more then that , I can continue with my loop until... forever - very
| confused
| Any case thank you all very much
| "Daniel" <Da*****@vestryonline.comwrote in message
| news:Oz**************@TK2MSFTNGP03.phx.gbl...
| Yeah i agree with Will, that would send a 0 bytes.
| >
| "William Stacey [MVP]" <wi************@gmail.comwrote in message
| news:eL**************@TK2MSFTNGP06.phx.gbl...
| >Sounds like peer socket is closing send before you receive. Did you
try
| >my
| >code?
| >>
| >--
| >William Stacey [MVP]
| >>
| >"semedao" <se*****@community.nospamwrote in message
| >news:OB**************@TK2MSFTNGP04.phx.gbl...
| >| Hi Daniel,
| >| this is exaclty what I already did!
| >| but , when I want to read the first 5 btes (my header , 1 more byte
for
| >| "command" ) , I receive the zero length !
| >| it's happen in the first read , before I start the loop of
| >| header->packet->header->packet...
| >|
| >| "Daniel" <Da*****@vestryonline.comwrote in message
| >| news:Ok**************@TK2MSFTNGP05.phx.gbl...
| >| Hey Sem
| >| >
| >| Since i have implemented what you are doing successfully and did in
| >fact
| >| get it right that you are 'losing' bytes i will continue to try and
| >help.
| >| >
| >| the reason i believe you are losing data is the exact reason that i
| >was
| >| when i first attempted this.
| >| >
| >| Ok imagine this, you send a total of 800 bytes, and your buffer is
| >500
| >| bytes in size (500 for arguments sake to keep numbers easy)
| >| >
| >| Your async socket listens and receives 500 bytes (your total buffer
| >size
| >| with still 300 to come), you read the full buffer and then finish.
| >Now
| >the
| >| next 300 comes through and so you receive 300 bytes.
| >| >
| >| So your second receive is a 500 byte buffer with only 300 byes of
| >data
| >in
| >| it.
| >| >
| >| So when you hit the 300th byte of that 500 check your code and see
if
| >at
| >| this point you stop reading, as after all you have your data, and
| >break.
| >| If so you just lost 200 bytes. Sure that 200 bytes may be empty but
| >it
| >| might not. If another send was done at the other end it may have
been
| >| joined on the end. and your break just ignored it.
| >| >
| >| So this is what you must remember:
| >| >
| >| 1) Send 4 bytes containing the ength of the data being sent
| >| 2) receiveing end, read first 4 bytes and store size of data to
come
| >| 3) read that many bytes and use the end of those bytes not as a
point
| >to
| >| break and say end of transmission but end of that object being
| >received
| >| and now...
| >| 4) ....now the next 4 bytes check for size again and so on ans so
on
| >| >
| >| So to clarfiy further. Imagine sending an object of 1024 bytes in
| >size.
| >We
| >| would do this
| >| >
| >| a) create 4 bytes containing the length of the data being sent, the
| >number
| >| 1024
| >| b) send the 4 bytes
| >| c) send the data
| >| d) receive and
| >| 1)first receive check first 4 bytes to get size expected
| >| 2) read that many bytes
| >| 3) on reading that many bytes check next 4 bytes received for
| >expected
| >| size of next data comin thorugh
| >| 4) if expected size now is 0 then no more to come, go back to
| >active
| >| waiting state
| >| 5) if not 0 then read as usual and so on
| >| >
| >| >
| >| Does that make sense?
| >| >
| >| >
| >| >
| >| >
| >| >
| >| "semedao" <se*****@community.nospamwrote in message
| >| news:OC**************@TK2MSFTNGP02.phx.gbl...
| >| >Hi , I take back my words about missing data... :))
| >| >ok ok , the data is missing , but , help me understand
| >| >why ??
| >| >firsy - yes , I am using TCP
| >| >now , If I made loop around the "beginRecv until it will return
the
| >| >expected buffer length , the app is in infinite loop in case when
| >the
| >| >return of endrecv is zero.
| >| >so , how can I handle it ?
| >| >>
| >| >"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
| >| >news:12*************@corp.supernews.com...
| >| >>"Daniel" <Da*****@vestryonline.comwrote in message
| >| >>news:%2****************@TK2MSFTNGP03.phx.gbl.. .
| >| >>>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?
| >| >>>
| >| >>Not necessarily. All we know is that he doesn't receive the data
| >when
| >| >>he expected to. Since he has no loop around his receive attempt,
| >he
| >| >>definitely will fail to read the data if it's not read the first
| >time
| >| >>through. But the data remains on the socket, until such time as
it
| >IS
| >| >>read or the socket is closed. It's entirely possible that his
code
| >does
| >| >>eventually read the data, preventing it from being lost.
| >| >>>
| >| >>I'd say if he says he doesn't lose data, we should take his word
| >for
| >it,
| >| >>at least for the moment. :)
| >| >>>
| >| >>In addition...
| >| >>>
| >| >>>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.
| >| >>>
| >| >>All true. However, the thing that many programmers miss (and
which
| >you
| >| >>didn't mention) is that you may not even receive 10 bytes or 5
| >bytes
| >or
| >| >>any given number of bytes for any given call to receive.
| >| >>>
| >| >>In your example, the sender sends 20 bytes. The receiver may in
| >fact
| >| >>wind up receiving 1 byte at a time, 20 times, and the code must
be
| >| >>prepared to deal with this. In reality, the extreme cases almost
| >never
| >| >>happen (eg getting just one byte at a time) but the API
| >specification
| >| >>doesn't guarantee anything better than that, and if your code
isn't
| >| >>handling that degenerate case, it likely also doesn't handle the
| >more
| >| >>likely cases as well.
| >| >>>
| >| >>With a stream-oriented socket (eg TCP), there are no message
| >boundaries.
| >| >>The way the data is grouped during the send has nothing to do
with
| >the
| >| >>way the data is grouped during the receive.
| >| >>>
| >| >>Now, as it happens, we don't really know whether the original
| >poster
| >is
| >| >>using a stream-oriented socket. I didn't see anything in his
post
| >or
| >| >>code that implies TCP (or similar protocol). If he's using UDP,
| >all
| >of
| >| >>the above isn't relevant and there's a whole different set of
| >| >>considerations (ie, one receive always returns exactly what one
| >send
| >| >>sent, but you may receive the same datagram more than once, not
at
| >all,
| >| >>or out of order from the other datagrams).
| >| >>>
| >| >>The real issue here appears to be what "blocking" and
| >"non-blocking"
| >| >>mean with respect to the .NET implementation of sockets. I
suspect
| >that
| >| >>even though the documentation says otherwise, the EndReceive
method
| >only
| >| >>blocks until the receive is completed when a blocking socket is
| >used
| >| >>(and of course, as you point out, for a TCP socket "complete"
does
| >not
| >| >>necessary mean "the buffer has been filled"...it just means
*some*
| >data
| >| >>has been received).
| >| >>>
| >| >>Pete
| >| >>>
| >| >>
| >| >>
| >| >
| >| >
| >|
| >|
| >>
| >>
| >
| >
|
|
Sep 17 '06 #19

P: n/a
Yep i concur wit the later posts, not knowing that a socket close sends a 0
byte is a little worrying. Definitely re-read the documentation. when i
started i had to read it hundreds of time suntil i fully understood *blush*
but it's wirth it because not having 100% understading will lead to a world
of pain, trust me i know ;)

When i first implememtned it i had lots of things that werent quite right,
which i only discovered later on truly understanding the way it works. The
thing is, i was still able to send and receive data, sometimes data didn't
make it, or a serrilisation error would occur 'seemingly' random and so on.
So just becuase you can send data and receive doesn't mean it is correctly
implemented.

When it is correctly implemetned you will have no issues sending and
receiving data and all data will always make it, remember that ;)

A way of helping which i did was to do this. Write out to the console when
you receive data nd how much you were expecting. So write out the header and
then when data come sin how much is read. Do the same when sending. And
check it's always matching up. You will very quickly spot issues.

D
"William Stacey [MVP]" <wi************@gmail.comwrote in message
news:uY*************@TK2MSFTNGP06.phx.gbl...
Shutdown.Send is not an exception, it is expected behavior (at some
point) -
same with using socket directly. You must always check for 0 return.

--
William Stacey [MVP]

"semedao" <se*****@community.nospamwrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
| friends !
| You right - the sender close the socket (for other bug reasons that I
still
| need to understand why happen onlywhen running and not step by step...
:) )
| and that's what cause the WaitOne to signald and then the EndReceive
return
| zero , but what I didn't understand is why it's does not throwme a
| SocketException ???
| if the exception was throw - it was so much easy to debug!
| more then that , I can continue with my loop until... forever - very
| confused
| Any case thank you all very much
| "Daniel" <Da*****@vestryonline.comwrote in message
| news:Oz**************@TK2MSFTNGP03.phx.gbl...
| Yeah i agree with Will, that would send a 0 bytes.
| >
| "William Stacey [MVP]" <wi************@gmail.comwrote in message
| news:eL**************@TK2MSFTNGP06.phx.gbl...
| >Sounds like peer socket is closing send before you receive. Did you
try
| >my
| >code?
| >>
| >--
| >William Stacey [MVP]
| >>
| >"semedao" <se*****@community.nospamwrote in message
| >news:OB**************@TK2MSFTNGP04.phx.gbl...
| >| Hi Daniel,
| >| this is exaclty what I already did!
| >| but , when I want to read the first 5 btes (my header , 1 more byte
for
| >| "command" ) , I receive the zero length !
| >| it's happen in the first read , before I start the loop of
| >| header->packet->header->packet...
| >|
| >| "Daniel" <Da*****@vestryonline.comwrote in message
| >| news:Ok**************@TK2MSFTNGP05.phx.gbl...
| >| Hey Sem
| >| >
| >| Since i have implemented what you are doing successfully and did
in
| >fact
| >| get it right that you are 'losing' bytes i will continue to try
and
| >help.
| >| >
| >| the reason i believe you are losing data is the exact reason that
i
| >was
| >| when i first attempted this.
| >| >
| >| Ok imagine this, you send a total of 800 bytes, and your buffer
is
| >500
| >| bytes in size (500 for arguments sake to keep numbers easy)
| >| >
| >| Your async socket listens and receives 500 bytes (your total
buffer
| >size
| >| with still 300 to come), you read the full buffer and then
finish.
| >Now
| >the
| >| next 300 comes through and so you receive 300 bytes.
| >| >
| >| So your second receive is a 500 byte buffer with only 300 byes of
| >data
| >in
| >| it.
| >| >
| >| So when you hit the 300th byte of that 500 check your code and
see
if
| >at
| >| this point you stop reading, as after all you have your data, and
| >break.
| >| If so you just lost 200 bytes. Sure that 200 bytes may be empty
but
| >it
| >| might not. If another send was done at the other end it may have
been
| >| joined on the end. and your break just ignored it.
| >| >
| >| So this is what you must remember:
| >| >
| >| 1) Send 4 bytes containing the ength of the data being sent
| >| 2) receiveing end, read first 4 bytes and store size of data to
come
| >| 3) read that many bytes and use the end of those bytes not as a
point
| >to
| >| break and say end of transmission but end of that object being
| >received
| >| and now...
| >| 4) ....now the next 4 bytes check for size again and so on ans so
on
| >| >
| >| So to clarfiy further. Imagine sending an object of 1024 bytes in
| >size.
| >We
| >| would do this
| >| >
| >| a) create 4 bytes containing the length of the data being sent,
the
| >number
| >| 1024
| >| b) send the 4 bytes
| >| c) send the data
| >| d) receive and
| >| 1)first receive check first 4 bytes to get size expected
| >| 2) read that many bytes
| >| 3) on reading that many bytes check next 4 bytes received for
| >expected
| >| size of next data comin thorugh
| >| 4) if expected size now is 0 then no more to come, go back to
| >active
| >| waiting state
| >| 5) if not 0 then read as usual and so on
| >| >
| >| >
| >| Does that make sense?
| >| >
| >| >
| >| >
| >| >
| >| >
| >| "semedao" <se*****@community.nospamwrote in message
| >| news:OC**************@TK2MSFTNGP02.phx.gbl...
| >| >Hi , I take back my words about missing data... :))
| >| >ok ok , the data is missing , but , help me understand
| >| >why ??
| >| >firsy - yes , I am using TCP
| >| >now , If I made loop around the "beginRecv until it will return
the
| >| >expected buffer length , the app is in infinite loop in case
when
| >the
| >| >return of endrecv is zero.
| >| >so , how can I handle it ?
| >| >>
| >| >"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
| >| >news:12*************@corp.supernews.com...
| >| >>"Daniel" <Da*****@vestryonline.comwrote in message
| >| >>news:%2****************@TK2MSFTNGP03.phx.gbl.. .
| >| >>>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?
| >| >>>
| >| >>Not necessarily. All we know is that he doesn't receive the
data
| >when
| >| >>he expected to. Since he has no loop around his receive
attempt,
| >he
| >| >>definitely will fail to read the data if it's not read the
first
| >time
| >| >>through. But the data remains on the socket, until such time
as
it
| >IS
| >| >>read or the socket is closed. It's entirely possible that his
code
| >does
| >| >>eventually read the data, preventing it from being lost.
| >| >>>
| >| >>I'd say if he says he doesn't lose data, we should take his
word
| >for
| >it,
| >| >>at least for the moment. :)
| >| >>>
| >| >>In addition...
| >| >>>
| >| >>>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.
| >| >>>
| >| >>All true. However, the thing that many programmers miss (and
which
| >you
| >| >>didn't mention) is that you may not even receive 10 bytes or 5
| >bytes
| >or
| >| >>any given number of bytes for any given call to receive.
| >| >>>
| >| >>In your example, the sender sends 20 bytes. The receiver may
in
| >fact
| >| >>wind up receiving 1 byte at a time, 20 times, and the code must
be
| >| >>prepared to deal with this. In reality, the extreme cases
almost
| >never
| >| >>happen (eg getting just one byte at a time) but the API
| >specification
| >| >>doesn't guarantee anything better than that, and if your code
isn't
| >| >>handling that degenerate case, it likely also doesn't handle
the
| >more
| >| >>likely cases as well.
| >| >>>
| >| >>With a stream-oriented socket (eg TCP), there are no message
| >boundaries.
| >| >>The way the data is grouped during the send has nothing to do
with
| >the
| >| >>way the data is grouped during the receive.
| >| >>>
| >| >>Now, as it happens, we don't really know whether the original
| >poster
| >is
| >| >>using a stream-oriented socket. I didn't see anything in his
post
| >or
| >| >>code that implies TCP (or similar protocol). If he's using
UDP,
| >all
| >of
| >| >>the above isn't relevant and there's a whole different set of
| >| >>considerations (ie, one receive always returns exactly what one
| >send
| >| >>sent, but you may receive the same datagram more than once, not
at
| >all,
| >| >>or out of order from the other datagrams).
| >| >>>
| >| >>The real issue here appears to be what "blocking" and
| >"non-blocking"
| >| >>mean with respect to the .NET implementation of sockets. I
suspect
| >that
| >| >>even though the documentation says otherwise, the EndReceive
method
| >only
| >| >>blocks until the receive is completed when a blocking socket is
| >used
| >| >>(and of course, as you point out, for a TCP socket "complete"
does
| >not
| >| >>necessary mean "the buffer has been filled"...it just means
*some*
| >data
| >| >>has been received).
| >| >>>
| >| >>Pete
| >| >>>
| >| >>
| >| >>
| >| >
| >| >
| >|
| >|
| >>
| >>
| >
| >
|
|


Sep 17 '06 #20

P: n/a
I hope somebody is still reading this..
I have a similar problem and i'm not sure what to do. Let me start off
by saying that this is my first dive into the world of sockets.
I got some free c sharp code for a simple ftpclient.
I've been playing around with it some, trying to write a function to
return the size of a given directory on the ftp server. I think the
issue i ran into is similar to what's been discussed here but not
exactly.
In my scenario i use the straight Receive to get the data from the ftp
server and here's what i noticed. When i run the code with some
console.writeline's or step through it in a debugger it runs just
fine.
As soon as i remove the console.writeline's it fails - the size of data
received is not what its supposed be. Here is the code that executes
when this happens:

socket is created like this:
socket = new
Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
ep = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port);
socket.Connect(ep);

and then used like this:
DateTime timeout = DateTime.Now.AddSeconds(this.timeoutSeconds);

while( timeout DateTime.Now )
{
int bytes = cSocket.Receive(buffer, buffer.Length, 0);

//if i put some Console.Writeline here it will work
otherwise it fails.
this.message += ASCII.GetString(buffer, 0, bytes);

if ( bytes < this.buffer.Length) break;
}

I'm assuming i'm experiencing the same problem ie the peer socket
closing before it's read

Please advise me on how to resolve this.

Sep 20 '06 #21

P: n/a
Hi Martin
how it's fail ?
throw exception or , return 0 bytes ?
if it's throw exception let's try to read it
if it's return zero bytes - based on my problem and the nice people help me
here - it's mean that the second party shutdown the connection

<ma*****@senecadata.comwrote in message
news:11*********************@d34g2000cwd.googlegro ups.com...
>I hope somebody is still reading this..
I have a similar problem and i'm not sure what to do. Let me start off
by saying that this is my first dive into the world of sockets.
I got some free c sharp code for a simple ftpclient.
I've been playing around with it some, trying to write a function to
return the size of a given directory on the ftp server. I think the
issue i ran into is similar to what's been discussed here but not
exactly.
In my scenario i use the straight Receive to get the data from the ftp
server and here's what i noticed. When i run the code with some
console.writeline's or step through it in a debugger it runs just
fine.
As soon as i remove the console.writeline's it fails - the size of data
received is not what its supposed be. Here is the code that executes
when this happens:

socket is created like this:
socket = new
Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
ep = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port);
socket.Connect(ep);

and then used like this:
DateTime timeout = DateTime.Now.AddSeconds(this.timeoutSeconds);

while( timeout DateTime.Now )
{
int bytes = cSocket.Receive(buffer, buffer.Length, 0);

//if i put some Console.Writeline here it will work
otherwise it fails.
this.message += ASCII.GetString(buffer, 0, bytes);

if ( bytes < this.buffer.Length) break;
}

I'm assuming i'm experiencing the same problem ie the peer socket
closing before it's read

Please advise me on how to resolve this.

Sep 21 '06 #22

P: n/a
Its seems to be the latter. I dont get errors just no results returned.
The machine i connect to is our company ftp server so i dont understand
why it would be closing the socket. Anyway the socket's Connected
property returns true. I really dont know what to do with it.

Sep 21 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.