Security and troubleshooting

Design a tiny text protocol

Use the local TCP lab to define commands, replies, framing, errors, and connection closure for a protocol of your own.

You have read HTTP and SMTP by hand. Now design a protocol of your own. We will extend the local Node.js server with three commands: TIME, ECHO text, and QUIT.

Frame the input

The first decision in any text protocol is where a message ends. Pick one line ending, CR LF, and buffer input until a complete line arrives:

let buffer = ''

socket.on('data', chunk => {
  buffer += chunk.toString('utf8')
  let index
  while ((index = buffer.indexOf('\r\n')) !== -1) {
    const line = buffer.slice(0, index)
    buffer = buffer.slice(index + 2)
    handleLine(socket, line)
  }
})

The while loop matters. One data event may carry zero, one, or three complete lines. TCP gives you a stream, so one data event is not the same as one command. Anything left in buffer after the loop is a partial line, waiting for the rest.

Shape the replies

Return one numeric reply per command, SMTP-style:

200 2026-08-03T10:00:00Z
200 hello
400 unknown command
221 bye

Numeric codes let a client program check the first three characters without parsing the whole line. Humans read the text after the code. Machines read the code. You saw SMTP do exactly this a few lessons ago.

Test the happy path

Connect with your Telnet client and try each command:

TIME
200 2026-08-03T10:00:00Z
ECHO hello
200 hello
QUIT
221 bye
Connection closed by foreign host.

QUIT should reply and then close the socket, so the client prints that last line on its own.

Test the ugly paths

Now try to break it. Send an unknown command and confirm you get 400 unknown command instead of silence. Send an empty line. Send a very long line and watch what your server does with it.

Then test two commands arriving in one read. Netcat can do that:

printf 'TIME\r\nECHO hi\r\n' | nc 127.0.0.1 2323

That delivers two commands in a single write. If your server only answers one of them, the while loop is missing or wrong.

Write the contract down

Document the command grammar, the reply grammar, the encoding, the maximum line length, the timeout, and the close behavior. A protocol without a maximum line length invites a client to send an endless line and eat your memory. A protocol without a timeout collects dead connections forever.

You now have an application protocol that a Telnet client can demonstrate. It is not the Telnet protocol, unless you also implement Telnet commands and negotiation. The distinction from earlier lessons applies to your own work too: the tool speaks TCP, and your protocol defines what the bytes mean.

Lesson completed