While I’m a newbie in socket programming, as I was writing a simple tcp server-client program, I found the stream-based api is not that convenient to use.
My program is simply simple:
- The client connects to a server
- The server continuously send messages to client, in a unexpectable interval
- The client receives message and do work according to the data contained in message
However, using the stream-based api, I have to:
- Define a message delimiter / separator
- Use a
whileloop to read data from stream - Concat all bytes, try to find the delimiter
- If delimiter exists, split the data, extract the message
That’s a lot work, even more than the entire logic of my program, so I’m wondering is there a library could do stuffs above for me, with such library I can program like this:
// Server
TcpListenerEx server = new TcpListenerEx();
TcpClientEx client = server.Accept();
client.SendMessage(new StringMessage("hello world"));
// Client
TcpClientEx client = new TcpClientEx();
client.Connect("localhost", 8989);
while (true) {
IMessage message = client.ReadMesage();
// Do work acording to message
}
Any suggestion would be welcome, thanks.
Embedding a delimiter in a byte-stream is not as easy as it might look. You’d have to deal with the message accidentally containing the delimiter. This leads to lots of nasty detection and escaping code.
A very simple way to frame messages is to prepend a length-prefix. On the sender you serialize the message into a buffer, then write the length, then write the buffer. The receiver first reads 4 bytes to obtain the length. Then it reads the body.
This is not built into .NET, probably because every binary protocol is slightly different.
All of this is so simple that it is unlikely you will find a library. Such a protocol can be written in a few dozen lines. My recommendation is to just do it yourself.
If you want to structure your message, though, there is a great library: protobuf-net (Google protocol buffers for .NET). It does message framing for you and also the serialization in a very sane way. It supports protocol versioning nicely.