Re: help out a boob? whats wrong with this? callback not firing when called recursively
- From: "David" <nospam@xxxxxxxxxx>
- Date: Mon, 30 Apr 2007 09:41:35 -0400
Thanks a million for the explanation Peter. I really appreciate it, and I
believe I have it straight now.
as far as the first part, I misunderstood what happens on that asynch
call... I thought a call to the BeginReceive always fired the associated
call back method, whether there was data to receive or not... I was thinking
if there was no data the EndReceive would return 0 (I know now that is
wrong), but even after learning when a 0 return does actually happen I was
thinking the call back would still be fired even when there is no data to
receive but that it would block, waiting for the data. (again, I know now
that is wrong)
and thanks for the explanation on the transactional scenario questions I
brought up... I got it now.
-David
"Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx> wrote in message
news:op.tri946fg8jd0ej@xxxxxxxxxxxxxxxxxxxxxxx
On Sat, 28 Apr 2007 15:29:34 -0700, David <nospam@xxxxxxxxxx> wrote:
thanks for the reply. I didn't realize that (0 byte won't happen until
sender closes connection). I just got it from a book... receive until 0
bytes...
1) no, sender has not closed the connection. But wouldn't that call back
method have at least fired and therefore I would see my
console.writelines
informing me I've entered the call back? Those are lines before I test
for 0 bytes...
I don't understand the question. You won't get a 0 byte receive until the
connection is closed. It seems that you now understand that much.
So, provided all of the data that's been sent has been received, what else
would cause the callback to be called, other than the connection being
closed? And if the answer to that is "nothing" (which I believe it is
) ), why would you expect the callback to be called?
You wrote the word "again" in context of the callback being called. I
agree that if you send data to the socket, you should get the callback at
least once. But if you receive all of the data in the first call, then
why would you expect to be called again before the socket is closed?
2) if you don't get 0 bytes until connection closed by sender how should
I handle situations where client and server are exchanging several
messages
back and forth?
Well, the first trick is to understand that a TCP connection doesn't know
anything about "messages". If you already understand that, you're halfway
there.
In other words, several consecutive send, receive, send,
receive etc... as part of one 'conversation'? I wouldn't think you would
want to open/close, open/close, etc.. sockets each time?
Well, that's exactly how some protocols do it (for example, some versions
of HTTP use a given connection for only one transaction...new requests
require new connections).
It's not as efficient as reusing a single connection for multiple
transactions, and in fact that's why HTTP now also allows for reusing
connections. But for low-bandwidth tasks, it's not actually a terrible
solution.
I've seen using a string like <eof> as an end of communication marker in
some microsoft
examples but I thought it didn't seem as elegant or something,
Well, that's one way to do it. It's plenty elegant if your data is always
printable characters and you provide a way to escape "<eof>" when
necessary (for example, what if you're moving USENET messages around and
someone happens to post a message to a newsgroup talking about how you can
use "<eof>" for the end of a transaction, you have to somehow escape or
quote the "<eof>" so that the "<eof>" written by the person posting isn't
incorrectly detected as the end of a transaction).
For strings, one delimiter that is popular is the null character (0). It
has the advantage of being defined as something you'd never actually see
in a string, so there's no need to use any sort of escape mechanism to
allow it to be included in a string.
For binary data, you could also use some kind of terminator. Even the
string "<eof>" would work, but the problem of escaping the data still
comes up. More common with binary data is to define the protocol so that
before the data is sent, the length of the data is sent in some
fixed-length form. This could be a text string parseable as the length,
or it could be binary data itself in some predefined format.
For large binary data, it seems to me that closing the connection is also
fine. After all, in that situation the overhead of closing and reopening
a connection is probably trivial compared to the cost of sending the data.
But really, there's a variety of ways to accomplish it and mainly it just
comes down to what you think works best for your protocol (keeping in mind
that if you're implementing an already-defined protocol, then it surely
also defines how transactions are delimited).
plus I was
thinking that your code is not controlling how the actual packets are
created and therefore it would be possible that an end of communication
string could wind up split up between packets and the receive buffer
could wind up with only part of it... ??
That's a problem whether you delimit your data or not. And you need to be
able to handle it. Over TCP, the data that is sent may be received in any
grouping. Any given receive could return as little as one byte and as
much as all of the rest of the data or the size of your buffer (whichever
is smaller of course :) ). But just as you need to be able to reassemble
the other data being sent to you, you need to be able to reassemble any
delimiters you might use (including byte counts sent before the rest of
the data).
Since reassembling delimiters isn't any different from reassembling the
rest of the data, it's not really an added complication, when you stop to
think about it. It's just part of the original complication.
I don't really know what I'm doing yet. I figured if you are receiving
data of variable sizes that you would want to loop receives until all
data is received, rather than guess on a buffer size that will always
work, so the code always works no matter how much data is coming.
The only way to have the code "always work" is to always check the byte
count for the received data and track how much data has come in so far,
and detect when you've received enough data to actually do something with
it.
The buffer size you use in the call to the receive method is not really
part of that. It relates more to how much data you want to be able to
pull from the network driver at once, and in that respect generally
speaking, the more the better. Obviously, that's an over-generalization,
but if you want to use the network efficiently and are moving a lot of
data, we're talking as much as 8 or 16K buffers. But more important, the
buffer size doesn't have anything to do with the reassembly of data after
it's been received; you need to handle that, and handling it is the same
regardless of the buffer size used to receive the data.
Pete
.
- References:
- help out a boob? whats wrong with this? callback not firing when called recursively
- From: David
- Re: help out a boob? whats wrong with this? callback not firing when called recursively
- From: Peter Duniho
- Re: help out a boob? whats wrong with this? callback not firing when called recursively
- From: David
- Re: help out a boob? whats wrong with this? callback not firing when called recursively
- From: Peter Duniho
- help out a boob? whats wrong with this? callback not firing when called recursively
- Prev by Date: Interoperatablity in c# and vb. Case Sensitivity issue.
- Next by Date: C# Profiler
- Previous by thread: Re: help out a boob? whats wrong with this? callback not firing when called recursively
- Next by thread: Alternatives to "Guid"
- Index(es):
Relevant Pages
|
Loading