People write their own encoders/decoders (codecs) because Netty doesn't impose nor define an application level protocol, so that you are free to write your own protocol. The set of codecs you define is a protocol that can be anything between String based and some binary format as Protobuf, for example. Netty provides codecs for your convenience (the ones you used are examples).
I would assume this is to keep the stream from being cutoff early?
Usually, when you are sending/receiving streams, you need to decompose that on a fixed length chunks (called frames). A popular approach, that has been used since the dawn of the Internet, is to use the length of the chunk (usually a 4 bytes int) as the first field read from the stream. So if the value of the first int is 20 then you know that the following 20 bytes are the payload (the data), and the 21th byte is the first byte of another length. The advantage of this approach is that it allows chunks of variable length. But you are not limited to this. For example, if you plan to write a protocol that uses Strings with predefined length (with padding) then you'll write or, even better, use Netty current codecs appropriate to it.
Once, I implemented a protocol with three decoders that would perform in this order:
- receive a stream and decompose it in length prefixed frames;
- convert each frame to a string;
- use Jackson libray to convert a string to a predefined Java object.
The encoders would just do the same operations, but backwards. Unfortunately, I've lost the original code, but I will rewrite it soon.
But how does the stream know that the stream is a String or a series of int's or a series of doubles? How do you tell it the difference is the question?
Short answer: it doesn't know. You have to encode this info in the codecs. For example, you can use a opcode as the first field in the payload that says that payload are Strings, doubles, ints or any combination of both.
Basically, Netty provides a stream and you are free to decode as you like. For example, if you are reading a series of longs (8 bytes) then you are going to write a codec that reads 64 bytes at a time from the stream because each one represents a single long. Netty provides codecs out-of-box so that you don't need to reinvent the wheel every time.