Skip to Content
Course content

272: Building a Simple TCP Client and Server

Click on the "Edit" button in the top corner of the screen to edit your slide content.

TCP (Transmission Control Protocol) is the reliable "handshake" of the internet. Unlike UDP, where you just throw packets at a destination and hope for the best, TCP ensures that every byte arrives in the correct order. Today, we're going to build a small "Server Health Probe." The idea is simple: a client will connect to a server, ask for its current status, and the server will respond with a health report.

Setting up the Listening Post

First, we need a server that sits and waits for a connection. In Python, the socket module is our primary tool here. I'm going to use AF_INET for IPv4 and SOCK_STREAM to tell Python we want a TCP connection.

import socket

# We'll use localhost and a non-privileged port
HOST = '127.0.0.1' 
PORT = 65432

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()

print(f"Server is listening on {HOST}:{PORT}...")

while True:
    # This blocks until a client connects
    conn, addr = server_socket.accept()
    print(f"Connected by {addr}")
    
    data = conn.recv(1024)
    if not data:
        break
        
    print(f"Received request: {data.decode()}")
    
    # I'll send a simple status message back
    conn.send("STATUS_OK: All systems nominal")
    conn.close()

Wait, I just broke it

If you try to run that server code and connect to it, you'll hit a TypeError. I did this a dozen times when I first started with sockets. The error is: TypeError: a bytes-like object is required, not 'str'.

Here is the thing about sockets: they don't understand Python strings. They only understand bytes. When I called conn.send("STATUS_OK..."), I passed a string. I need to encode that string into bytes using UTF-8 before it hits the wire. I'll fix that line to: conn.send("STATUS_OK: All systems nominal".encode('utf-8')).

Connecting the Health Probe Client

Now that the server knows how to handle bytes, let's build the client. The client is much simpler; it doesn't need to bind or listen. It just needs to know where the server is and initiate the connection.

import socket

HOST = '127.0.0.1'
PORT = 65432

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
    client_socket.connect((HOST, PORT))
    
    # We have to encode the request string into bytes
    request = "GET_HEALTH"
    client_socket.sendall(request.encode('utf-8'))
    
    # Now we wait for the response
    response = client_socket.recv(1024)
    print(f"Server responded: {response.decode('utf-8')}")

Refining the Communication Flow

You'll notice I used sendall() in the client instead of send(). This is a professional habit I highly recommend. send() doesn't guarantee that all the data was actually transmitted—it returns the number of bytes sent, and you're technically supposed to keep track of the offset and send the rest in a loop. sendall() handles that tedious loop for you under the hood, ensuring the entire message is pushed through the buffer.

When you run these two scripts—server first, then client—you'll see the server log the connection, and the client print the health status. We've just built a minimal version of how almost every web request starts.




📋 Practical Task

Build a Remote System Clock Synchronizer

Your task is to extend the client-server pattern we just learned to create a "Time Sync" service.

  • The Server: Instead of returning a hardcoded "STATUS_OK" message, the server should import the datetime module. When it receives a request, it should capture the current server time as a string and send that back to the client.
  • The Client: The client should send the request "GET_TIME" and then print the received server time in a user-friendly format (e.g., "The server time is: 2023-10-27 14:30:05").

Ensure that both the client and server properly handle the encoding and decoding of bytes to avoid the TypeError we encountered in the lesson.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.