| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools | Rate Thread |
|
|
|
| |
|
semedao
Guest
Posts: 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 ? |
|
||
|
||||
|
semedao
Guest
Posts: 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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> 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 ? >> >> > > |
|
||
|
||||
|
Peter Duniho
Guest
Posts: n/a
|
"semedao" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)... > [...] > 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 |
|
||
|
||||
|
Daniel
Guest
Posts: 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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > "semedao" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> [...] >> 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 > |
|
||
|
||||
|
Peter Duniho
Guest
Posts: n/a
|
"Daniel" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)... > 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 |
|
||
|
||||
|
semedao
Guest
Posts: 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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > "Daniel" <(E-Mail Removed)> wrote in message > news:%(E-Mail Removed)... >> 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 > |
|
||
|
||||
|
Peter Duniho
Guest
Posts: n/a
|
"semedao" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)... > 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 |
|
||
|
||||
|
Daniel
Guest
Posts: 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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> "Daniel" <(E-Mail Removed)> wrote in message >> news:%(E-Mail Removed)... >>> 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 >> > > |
|
||
|
||||
|
William Stacey [MVP]
Guest
Posts: 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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... | 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 ? | | |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Step from VB6 to .Net (COM) in Debug Mode? | Terry | Microsoft VB .NET | 2 | 15th Aug 2008 10:13 PM |
| Debug/Step mode in macro/VBA | Jim | Microsoft Access VBA Modules | 3 | 30th Jul 2008 04:02 PM |
| step out and step in do not show on the Visual studio 2005 debug m | =?Utf-8?B?bWFydGluMQ==?= | Microsoft VB .NET | 0 | 30th Aug 2007 08:56 PM |
| Macro Works but not in Debug Step mode | Bob Smedley | Microsoft Excel Programming | 3 | 31st Jan 2006 04:28 PM |
| Debug Step vs Run Mode | Arthur | Microsoft Excel Programming | 3 | 9th Nov 2003 05:03 PM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |




