Resources
- Code (🇮🇹)
- Documentation (🇮🇹)
Highlights
Communication protocol
The communication between the client and the server operates at the lowest level: plain sockets. This required me to design a custom communication protocol from scratch
Let’s say the client wants to send the command USE cavo router
, the message is divided into two segments, sent sequentially:
- The first segment contains the size of the second segment. It is always encoded as a 2-byte big-endian integer
- The second segment contains the actual message:
- The first byte represents an action, in this case
USE
, which is translated to8
- From the second byte onward, the parameters are listed, separated by tildes
~
, with the final parameter ending in a null character\0
- The first byte represents an action, in this case
For example, the command above would be translated as 8cavo~router\0
Let’s check that using wireshark:
- The first TCP segment tells us that the expected length of the next segment is
13
: - In the second TCP segment, the message is encoded in the expected way:
A question may come naturally: why do i need to split a message and its size?
It is a very common newbie error to assume that every write() or send() on a TCP socket on the sending side will be matched by a read() or recv() from a TCP socket on the receiving side. This is not true. The sender might write() 200 bytes, and the first read() or recv() will return the first 50 bytes, only, and the next call returns the remaining 150 bytes. (Source : this stackoweflow answer)
Therefore, you can either:
- Send messages of fixed size, so that the receiver knows exatcly how many bytes to wait for
- First send the size, then send the message