HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Writing and reading of a custom binary protocol

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
readingprotocolwritingcustombinaryand

Problem

I'm currently trying to develop some code that will handle parsing and building of a custom binary protocol. The protocol itself
is still fairly fluid but the basic core features are decided. These include

  • It has a start and end deliminator



  • It contains a header and payload set of data. The header is standard and contains information such as the payload type, time of sending etc



  • Any strings or chars will be Ascii characters



Basic format is: [STX][Header][Payload][Checksum][ETX]


Note: I can't use libraries like proto-buf .net as the protocol
specification itself is outside of my control.

Any comments on code styling, design, implementation, best practices etc welcome.

Here is what I have come up with so far:

Data streams

```
public interface IDataInputStream
{
string ReadString(int count);
char ReadChar();
int ReadInt32();
short ReadIn16();
byte ReadByte();
}

public class DataInputStream : IDataInputStream, IDisposable
{
private readonly BinaryReader _reader;

public DataInputStream(Stream stream)
{
_reader = new BinaryReader(stream, System.Text.Encoding.UTF8);
}

public string ReadString(int count)
{
return new string(_reader.ReadChars(count));
}

public char ReadChar()
{
return _reader.ReadChar();
}

public int ReadInt32()
{
return _reader.ReadInt32();
}

public short ReadIn16()
{
return _reader.ReadInt16();
}

public byte ReadByte()
{
return _reader.ReadByte();
}

public void Dispose()
{
_reader.Dispose();
}
}

public interface IDataOutputStream
{
void Write(char value);
void Write(string value, int length);
void Write(int value);
void Write(short value);
void Write(byte[] value);
}

public class DataOutputStream : IDataOutputStream, IDisposable
{
private readonly BinaryWriter _writer;

public DataOutputStream(Stream stream)
{
_writer = ne

Solution

Protocol

It's strange to use a "custom protocol". Has no-one invented one you can reuse?

In a binary protocol with STX and ETX I'm used to seeing DLE being used as well:

  .


... with DLE in the payload being escaped as `.

I was surprised to find no "total packet length" or "total payload length" field in the packet header.

Your protocol doesn't handle variable-length strings in the payload well.

A one-byte checksum is pretty small.

This protocol doesn't recover from transmission errors well: if you lose a byte, then because you don't use
, you can't reliably find the start of the next packet (unless you guarantee that the STX char i.e. '$' is unique and never found in the header, not the payload, nor the checksum).

Text-based protocols can be easier to work with.

Code

Do you validate the received packet somewhere? Check that it starts with Stx, ends with Etx, and includes a valid checksum?

Your test code uses strings whose lengths are equal to the maximum field length; the receive code shows that short string will be zero-padded, but you don't have a unit-test for that.

BinaryReader is little-endian. Is your protocol little-endian too?

GetCommand returns
data[1]. Should it return data[2]: maybe data[0] is the STX and data[1]` is the Identifier?

Code Snippets

<DLE><STX> <PAYLOAD> <DLE><ETX>.

Context

StackExchange Code Review Q#44625, answer score: 4

Revisions (0)

No revisions yet.