0

So I'm currently writing a program that is essentially just a server and a client. The idea is that I want them to be able to communicate with one and other by sending packets back and forth. And I'm trying to figure out how to properly deal with this. This is my current flow of things.

  1. I start the server and wait for incomming connections.
  2. The client connect to the server and sends a packet which looks like this (0x1) which is the first and only byte indicating the opcode.. I want to send more data with this packet and this is where the "problem" occurs. I'm not sure how to serialize the packet.

The data I want to send is a string that can be anywhere from 2, 50 characters, followed by an ip address and a couple of more strings (2 or so) that have the length of 10 - 20 characters.

Now, would I just start by creating an array of bytes, appending the first byte (opcode) followed by the string that is not a fixed size string.. That's going to be hard to deserialize. Do I include the length of said string prior to the bytes of that string?

1
  • Whatever you do in your own application layer protocol is up to you. You use either fixed-size fields, TLV-style tagging, or start/end tags (e.g. XML). However, programming questions are off-topic here and should be asked on Stack Overflow.
    – Zac67
    Aug 22, 2020 at 11:12

1 Answer 1

2

You should design your first wire protocol with a header before each data field, such as [ Length, Type, Value ]. A common header will make serializing and debugging easy.

Be sure to think about if you want your protocol to work over a stream channel, like a TCP connection; or a packet/datagram channel, like UDP, as well. This might influence whether you need to encode the length of your entire message/operation when you transmit it (TCP) or can simply infer that length is the total length of a received datagram (UDP.)


It's a good idea to learn about some existing protocols, maybe ones you're familiar with using (but not programming an implementation of), to build up a conceptual basis prior to designing your own protocol. Walk before you run, as they say.

BGP was a good example for me early in my career, as I both used it in practice, and wanted to understand more about implementing serializer / deserializer code.

I suggest you look at the various BGP message and attribute formats. They are documented beginning in RFC4271 §4.

The reason I suggest BGP as an example for you is BGP uses several different techniques to encode data. It was developed over many years and the priorities of the design shifted a little bit over time, from compactness to ease-of-implementation and extensibility.

So for example, some fields have a fixed length which is never encoded directly into the BGP messages. Others are flexible and write their length in.

Additionally, some fields contain headers that re-use common flags for different types of attributes. This is a feature that makes implementation easier and more obvious. Path Attributes are a good example (though they are first documented as part of the UPDATE message that carry them.)

Further, BGP is so extensible that the global network of BGP routers don't all have to support all its features for those features to work correctly. BGP attributes which are unknown to a router can still pass through it to neighboring routers, while following various rules.

Finally, because BGP is such an old protocol, which has been extended many times with new features, you can see practical examples of how that worked. A good example is BGP Extended Communities.


Hope this helps!

Not the answer you're looking for? Browse other questions tagged or ask your own question.