Network programming with Python sockets: TCP client and server basics
In short: A socket is a program’s endpoint for network communication, identified by an IP address, port and protocol. Python’s socket module lets you build TCP and UDP clients and servers. Writing a small echo server and client shows how ports, handshakes and timeouts really behave.
What a socket is
A socket is the interface a program uses to send and receive data over a network. Each connection is identified by protocol, local address and port, and remote address and port. Higher-level libraries such as requests or Netmiko all sit on top of sockets. Writing a few socket programs yourself makes ideas such as ports, the TCP handshake and timeouts concrete.
A simple TCP echo server and client
The server binds to an address and port, listens, then accepts each connection, which gives a new socket for that client. This example only listens on the loopback address 127.0.0.1, so it is not reachable from other machines.
# echo_server.py
import socket
HOST, PORT = "127.0.0.1", 5050
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as srv:
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind((HOST, PORT))
srv.listen()
print(f"Listening on {HOST}:{PORT}")
conn, addr = srv.accept()
with conn:
print("Client", addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data.upper())
# echo_client.py
import socket
with socket.create_connection(("127.0.0.1", 5050), timeout=5) as s:
s.sendall(b"hello from the client")
print(s.recv(1024).decode())
Run the server in one terminal and the client in another. Sockets send bytes, not text, so encode strings with .encode() and decode replies with .decode(). Note that one recv() may return only part of a message: TCP is a stream, not a series of messages, so real protocols add lengths or delimiters.
UDP and a reachability check
UDP sockets have no connection: you send a datagram with sendto() and read with recvfrom(). No reply might mean the packet was lost, filtered or simply ignored. For engineers, the most practical socket job is checking whether a TCP service answers, for example after a firewall change.
import socket
def tcp_port_open(host: str, port: int, timeout: float = 2.0) -> bool:
try:
with socket.create_connection((host, port), timeout=timeout):
return True
except OSError:
return False
for port in (22, 443):
print(port, tcp_port_open("192.168.10.1", port))
Tip: only test hosts and networks you own or are authorised to test. Repeated connection attempts across many ports look like a port scan, may trigger alerts and can breach policy or the law.
Common mistakes and security points
- No timeout: a blocked connection can hang a script forever. Always set one.
- Binding to 0.0.0.0 exposes a test server to the whole network. Use 127.0.0.1 unless you mean it.
- "Address already in use": a recently closed port is still in the TIME_WAIT state.
SO_REUSEADDRhelps in testing. - Plain text: raw sockets are unencrypted. Wrap them with the
sslmodule, or better, use an existing protocol such as HTTPS or SSH. - Trusting input: a server must treat everything it receives as untrusted. Limit message sizes and validate content.
| Call | Side | Purpose |
|---|---|---|
bind() | Server | Claim a local address and port |
listen() / accept() | Server | Wait for and accept TCP clients |
create_connection() | Client | Resolve, connect and set a timeout |
sendall() / recv() | Both | Exchange bytes over TCP |
sendto() / recvfrom() | Both | Exchange UDP datagrams |
Practice
Why does accept() return a new socket?
A client calls recv(1024) once and gets half a message. Is that a bug in TCP?
Why bind a test server to 127.0.0.1 rather than 0.0.0.0?
Key takeaways
- A socket is identified by protocol, addresses and ports.
- TCP sockets carry a reliable byte stream; UDP sockets send datagrams.
- Servers bind, listen and accept; clients connect.
- Always set timeouts and work in bytes, not text.
- Only test systems you own; use TLS or existing protocols for real data.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.