Challenge, Medium,  on  NetworkingProgrammingLinux

Write a TCP Client for a Chat Server

A TCP connection is a symmetric, bidirectional byte stream - and it has no idea where one "application message" ends and the next begins. That becomes a problem the moment you want to design a communication protocol on top of it, and a simple chat server illustrates it very well.

The application has to impose its own structure on the raw byte stream sent over a TCP connection, and one of the simplest ways to do that is to delimit messages with a newline (\n).

In the telemetry client challenge you only had to connect() and read a one-way push stream. This time, you'll go a step further and hold a real back-and-forth conversation with a server.

Berkeley Sockets API Cheat Sheet.

Berkeley Sockets API cheat sheet.

The Task

A chat server is running on a separate host at 172.16.0.10:5000. It speaks a simple line-based protocol:

  1. The server reads one line at a time - everything up to and including a \n is one message.
  2. For every message you send, it answers with one line of gibberish, like:
    wibble zonk frobnicate quux sig=9f3a1c0b7e2d4a85
    

The content of the lines you send doesn't matter (hello\n is perfectly fine) - what matters is that each one is a complete, newline-terminated message.

Your task is to write a client that holds a short conversation with the server:

  1. Connect to 172.16.0.10:5000 from the dev-01 machine.
  2. Send at least 3 messages, reading the server's reply after each one.
  3. Save the server's replies into ~/chat.log so they can be verified.

You can use any language to write your client. The playground already has gcc (for C/C++), Python, Node.js, and Go installed. If you prefer a different stack, install it yourself.

Hint 1: The conversation loop

After connect()-ing, the client needs to:

  1. Read a single line from the user.
  2. Send it to the server (ensuring it ends with a \n).
  3. Read a full line back from the server.
  4. Print that reply so it can be copied into the transcript at ~/chat.log.

The client section of the How Servers Work tutorial shows the basic connect() / send() / recv() skeleton you can build this on.

Hint 2: Framing what you send

The server won't react until it sees a \n - that's how it knows one message has ended. So every line you send must be terminated with a newline. If you send() "hello" without the \n, the server keeps waiting for the rest of the line and never replies, and your client blocks forever on the next read.

Hint 3: Framing what you receive

TCP doesn't preserve message boundaries, so a single recv() may hand you only part of a line - the server's reply can be split across several reads. Don't assume one recv() returns one whole message.

Work with the raw recv() calls and reassemble lines yourself: keep an incoming buffer, append whatever each read returns, and keep reading until the buffer holds a complete line (everything up to the \n). Then split that line off and keep any leftover bytes in the buffer for next time. That little buffer is the whole trick to reading a line-oriented protocol off a byte stream.

Hint 4: Capturing the transcript with tee

The verifier looks for the server's replies in ~/chat.log. Instead of writing the file from your client, just print every line you receive from the server to stdout and let the shell capture it with tee:

./chat_client | tee ~/chat.log

That keeps your client code focused on the conversation while the transcript lands in the file for the check.