
Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
<snip>
> You're also assuming that you'll have the whole of a line as the result
> of the read, which may well not be the case.
[quoted text clipped - 3 lines]
> message has finished. Don't start looking at the message until you've
> got that much data.
Thanks Jon for your quick reply!
I did something slightly different, let me describe it: I introduced a
special symbol (I choose $, it's not used for anything else) to
signify the end of a message. Each time my read callback is called, I
extract all full messages. I also keep track of uncompleted messages.
The code doesn't currently handle if a message isn't completed the
next time the callback is called but I put an assertion for that case
for now and it hasn't triggered (shouldn't trigger very likely).
I had some problems first with message corruption that was very weird,
for example if I put a Trace.WriteLine() at sender it got worse on the
receiving end, but after making sure I send and receive a fixed-size
byte array and clear the receiving array each time those problems
disapperared.
Here's the read callback now, it's not very efficient, but at least it
seems to work now and I can continue implementing the actual card
game, heh:
private void OnReadMessage(IAsyncResult ar)
{
int total_bytes_read = this.tcp_client.GetStream().EndRead(ar);
String input = Encoding.ASCII.GetString(this.message, 0,
message.Length).Trim('\0');
int p1 = 0, p2 = 0;
while (p2 != -1)
{
p2 = input.IndexOf('$', p1);
if (p2 == -1)
{
Debug.Assert(being_built == false);
being_built = true;
semi_complete = input.Substring(p1);
}
else
{
String msg;
if (being_built)
{
msg = semi_complete + input.Substring(p1, p2 - p1 + 1);
being_built = false;
semi_complete = "";
}
else
{
msg = input.Substring(p1, p2 - p1 + 1);
}
p1 = p2 + 1;
tracebox.WriteLine(msg);
}
}
this.message = new byte[this.message_length]; // Important that we
clear this before each call.
this.tcp_client.GetStream().BeginRead(this.message, 0,
this.message_length, new AsyncCallback(this.OnReadMessage), null);
}
My next problem I need to tackle is the exceptions (IOExceptions
mostly I think) I get after closing the server or the client after
they have started communicating with each other. Any tips on that?
- Eric
> --
> Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
> World class .NET training in the UK:http://iterativetraining.co.uk
Jon Skeet [C# MVP] - 12 Mar 2008 09:36 GMT
> > I strongly suggest you design your protocol so that each message is
> > prefixed by its length, so it's easy to tell when any particular
[quoted text clipped - 5 lines]
> special symbol (I choose $, it's not used for anything else) to
> signify the end of a message.
Personally I prefer the length-prefix method. It can be pain if you
want to start sending a message before you know how long it is, but it
makes it much easier to make sure you've got all the data before you
start trying to do anything with it.
> Each time my read callback is called, I
> extract all full messages. I also keep track of uncompleted messages.
[quoted text clipped - 6 lines]
> byte array and clear the receiving array each time those problems
> disapperared.
Don't forget that just because you send and receive a certain size of
array doesn't mean you'll actually get that much data.
> Here's the read callback now, it's not very efficient, but at least it
> seems to work now and I can continue implementing the actual card
[quoted text clipped - 5 lines]
> String input = Encoding.ASCII.GetString(this.message, 0,
> message.Length).Trim('\0');
No - only decode the number of bytes you've read.
<snip>
> My next problem I need to tackle is the exceptions (IOExceptions
> mostly I think) I get after closing the server or the client after
> they have started communicating with each other. Any tips on that?
I would hope that EndRead would return 0 - that's how you should detect
it.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk