Parsing non length delimited data asynchronously

174 views Asked by At

I have a networked server that I switched to using synchronous Begin.. for handling short lived request, this was a huge improvement. For the long lived ones two threads are created and with the increasing number of clients it is starting to become a problem.

The data transferred over these connections are messages of 4 to 40 bytes. However they are not length-delimited and their length can depend on parts inside their message. And sadly I can't change the protocol. You can think of the protocol as a fast paced telnet terminal protocol.

I'm looking into reading and parsing the incoming messages/"lines" using Stream.BeginRead and have reached two worries:

  1. Is it efficient to call BeginRead about 3 times for a 10 byte message?
  2. How do I efficiently write the code doing this

Here is one example. Although the message itself is not length prefixed some of it's content may be.

Synchronous method(current)

int length = reader.ReadInt32();
byte[] buffer = reader.ReadBytes(length);

Asynchronous method

    ...
    //Here we have received a byte array
    int length = ParseIntegerFromBuffer(buffer);
    stream.BeginRead(buffer, 0, length, Part1Read, null);
}
private void Part1Read(IAsyncResult result)
{
    ...

The async example is not what I'm using, I've already written a few wrappers that take care of checking for successful read of the number of bytes requested. Is this as efficient in terms of writing and understanding the written code I can get?

My code must run on .NET 3.5 but in the future 5 is and option so should I wait for it and do the async programming then?

This code will face the internet and any hanging incoming connection would lock up a thread-pool thread if I used sync read.

1

There are 1 answers

0
hultqvist On

I completed the asynchronous implementation and the result was 4 times higher CPU load than a design with one thread per connection.

The protocol being parsed is badly designed in itself and trying to parse it asynchronously did not help managing more connections.