Building a simple TCP client in Python is one of the fundamental steps for anyone who wants to understand how the internet works under the hood. TCP (Transmission Control Protocol) is the foundation of nearly everything we do online, from browsing websites to sending instant messages. In this guide you will learn how to establish a network connection using Python’s built-in socket module, with no external libraries required.
What is a TCP client?
Think of the client-server architecture like a phone call: the server is waiting for the phone to ring, while the client is the one making the call. A TCP client initiates the conversation by requesting a connection to a specific IP address and port. Unlike UDP, TCP is connection-oriented: it guarantees that data arrives in the correct order and without errors, automatically requesting retransmission if a packet is lost.
Python manages this interaction through the socket module, which provides an interface to the Berkeley socket API. This is the industry standard for network communications across Linux, Windows, and macOS. The official Python socket documentation covers the complete API reference.
Step 1: Define the server address and port
import socketStep 2: Create the socket object
# AF_INET = IPv4 address family
# SOCK_STREAM = TCP protocol
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)Step 3: Connect and send data
Data sent over sockets must be in bytes, not strings. Use the b"" prefix for byte literals or call .encode() on a string. This is important to keep in mind when building any network tool. To run a server process in the background, see running terminal commands with Python.
# Connect to the server
client.connect((target_host, target_port))Step 4: Receive the response and close
# Receive the response (up to 4096 bytes)
response = client.recv(4096)TCP vs UDP: quick comparison
| Feature | TCP | UDP |
|---|---|---|
| Connection | Required (handshake) | Connectionless |
| Reliability | Guaranteed delivery and order | No guarantees |
| Speed | Slower (overhead) | Faster |
| Use cases | HTTP, FTP, SSH, databases | Video streaming, DNS, games |
Frequently asked questions
What does recv(4096) mean?
It means “receive up to 4096 bytes in one call.” This is the buffer size. For small messages it is usually enough; for large data transfers you need a loop that calls recv() repeatedly until all data arrives.
Should I always call client.close()?
Yes. Not closing the socket leaks file descriptors. Use a try/finally block or a context manager (with socket.socket(...) as client:) to guarantee cleanup even if an error occurs.
Can the socket module handle HTTPS?
Use ssl.wrap_socket() or Python’s ssl module to add TLS to a raw socket. For typical HTTP/HTTPS requests, the requests library is far more convenient.
Understanding socket-level TCP communication gives you the foundation to build custom network tools, proxies, and monitoring systems. Once comfortable with this, explore Python’s asyncio for handling multiple simultaneous connections efficiently.






