Hello DEV community.
I'm writing some code in C# using the .NET Core version 3.1
I need to communicate with another host which runs an old program on a TCP port that is using a custom byte-oriented protocol.
My side will be the client, since the other is a server listening on a specific port number.
I know I will need a
TCPClient function to open and establish a stream between the 2 hosts.
I have looked around for a NuGet package to help and I've found two: NetCoreServer and WatsonTcp.
Since this server is not always available, I might have to build a quick simulator app, so I'll have to do a
TCPListener function for that side too.
My question is: has anyone used these before or is there another I haven't found yet? Or maybe just use the classes already in the
System.Net.Sockets namespace (Microsoft provides examples that look fairly easy).
Any help from those with a lot more experience than me would be greatly appreciated.
Oldest comments (12)
This is out of my wheelhouse. I don't have much experience with this sort of thing. Good luck!
Thanks John. I had a feeling that most of the people here would be front-enders.
If you're sure it's Layer 4 (ie TCP/UDP) then the core Sockets lib is what everybody uses. Libraries that duplicate core functionality are few and far between.
If you have to work at a lower layer than that you'll need a lib built on top of a pcap driver. The tooling used to capture packets can also be used to format them as well. Libs that do one will usually do the other.
SharpPcap was a good choice back when I did that sort of thing (ie 10 years ago).
I’m pretty sure it’s just a layer 4 app but I’ll see if I need to go any lower. Thanks Evan.
Reading over my notes it’s definitely just layer 4. The next thing to look at is this byte stream which I need to figure out how to deserialize into classes. And I guess there should be a serialize counterpart.
Now I’m starting to think I might like front-end work better than pushing bytes around!
OK, good 👍
FrontEnd is usually easier to work with b/c everything is stringly-typed (ie everything is a string). Very inefficient but it's easy to work with.
If this isn't stringly-typed, you have some work to do.
First, parsing binary is where protocols come into play. A protocol is just a convention for structuring data. If you know the protocol used, you can look up its structure and build your own serialize and deserialize methods to match.
Conversion from binary to types is built into every language. In C# every type has an associated class. Even primitive types; for example int -> Int32. These classes all peovide a method to parse raw binary into the a value of that type.
The rest is just extracting out the correct number of bytes to match the type (ex double = 64bit = 8 bytes) from the buffer and parsing it into a value.
For boolean types (aka flags), you'll need to use bitwise operations to read (AND) write (OR) and toggle (XOR) the flags.
Hope you're comfortable working in a live debugger. The ability to step through the parser one-step at a time and address mistakes precisely will make the work go a lot faster.
On a positive note, once you're done with the parse/deserialize step; serialization is much easier. Convert each type to binary using the class, append the binary to your buffer byte-stream. That becomes the packet payload.
Hopefully, you can find documentation for the format/protocol used.
Reverse-engineer a protocol from binary is considerably more difficult. I've been there, it's not fun.
Easy, but highly prone to people's comments like Why did use use that font?
I know the structure. It looks like I need a BinaryFormatter to get the array into a MemoryStream
Yes, I've been working in Visual Studio for a while and can set conditional breakpoints, step through my code and watch variables. (It's how I really learn how C# works!)
I just hope this doc I have is accurate.
Evan, it's so nice of you to help me out. Thanks so much for the support.
Thanks Chris. That looks like the route I will be taking. Next task is byte stream serialization/deserialization.
I write lots of of low level protocols over TCP, and .NET Cores standard socket library sounds like all you need.
The general idea is to thinly layer your design so the protocol part is independent of the underlying sockets. I'm not sure what your protocol looks like, but you will likely want some kind of protocol class that manages a statemachine of the protocol. This protocol class just needs to understand ByteStream and a concept of Connection ( you could make something like a IByteStreamConnection )
Then it becomes pretty easy to unit test, you simply look at the details of the protocol create packets of bytes ( you will likely want to make some kind of 'Packet' class for making encoding and decoding of packets easier. Feed the packets of bytes to your protocol, verify the intended result happens ( hard to know exactly what you are doing )
Thank you Keith. I will be using the low level standard library class TCPClient. I'm juggling with the threads for send and receive right now. There is also a requirement for a heartbeat to be sent every minute, so I'll have a timer or two involved.
It looks like the designer of the protocol was a junior developer. A length field is used a lot and it's formatted differently in many places. For instance, a 2 byte length field of value 6 might be 0x00 0x06 in one place and 0x06 0x00 somewhere else. When an Ascii string is sent it gets prepended with a 2 byte length in Ascii! (0x36 0x30)