5

I've written a multi-threaded simple server that uses:

clientStream.Read(message, 0, 4096);

To block until the client has sent a message. The code then goes on to process that message.

So far I've only been using it to send short commands

ex. "#login[username][login]"

but I'm worried that when I send huge table data over the line the code may continue before it has all been received.

So will .Read block until the whole sent message is received, or does it unblock when any data has begun receiving?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Adrian Seeley
  • 2,262
  • 2
  • 29
  • 37

1 Answers1

8

Relying on a Send to finish to delineate between messages is bad form. If not for the simplest of reasons. I can telnet into your server and easily crash it.

You'll need to create a wire protocol. You have a few options.

  • Always expect the size of the message as a Unsigned 32-bit integer as the first 4-bytes, then read until you've filled that amount of data.

  • Specify a End of Message delimiter. This means you will maintain a buffer. You fill it with data off the wire, quickly scan it for end of message. Once you find a message you throw it to a message processor, then continue on with the left over bytes in the buffer, repeating step 1.

You can look at STOMP for an easy text based protocol.

Don't rely on your packets being sent in nice well-defined chunks as the message delimiter.

Andrew T Finnell
  • 13,417
  • 3
  • 33
  • 49
  • That's exactly what I figured, thank you for saving me hours of searching trying to figure out that little tidbit. So perhaps a better sample packet would look like this: #login[username][password]$ – Adrian Seeley Jun 12 '11 at 13:57
  • Another option would be if the message processor accepted `TextReader` (assuming the protocol is text-based). That way, you don't have to know the message size before reading it, you don't have to have end of message delimiter and you could potentially read huge messages without using too much memory. Of course, this means that there has to be clear way to find end of message, it just doesn't have to be clear on character level. – svick Jun 12 '11 at 13:59
  • I'm curious though how you would crash my server by telnetting into it. I think I've been fairly careful... But I am still learning! – Adrian Seeley Jun 12 '11 at 14:03
  • @Adrian I was being overly dramatic about my statement . If you assumed that all Reads result in a complete message, I could use telnet to send an incomplete or empty message. – Andrew T Finnell Jun 13 '11 at 03:32
  • Haha! My flow is a bit more: try(Block till read)catch all, then analyze for bad data. – Adrian Seeley Jun 13 '11 at 15:48