A zero-dependency cookbook for beginners. Everything below uses only the Python 3 standard library (socket, select, struct, hashlib, zlib, json, sys), flat procedural code, no asyncio, threads, or classes. Every script prints connections, messages and state changes so you can watch the protocol work. Run servers and clients in separate terminal tabs with python3 script.py <args>.
Part 1: Core Concepts & Standard Library Rules
- What a Socket Is: An Operating System endpoint that sends and receives raw bytes over a network.
- IP vs. Port: The IP address (
'localhost'or'127.0.0.1') identifies the machine; the Port (an integer like10000) identifies the specific Python process. - Networks Only Speak Bytes (
b"..."): Convertstrtobytesbefore sending with.encode(), and convert receivedbytesback tostrwith.decode(). - TCP (
SOCK_STREAM) vs. UDP (SOCK_DGRAM):- TCP is connection-oriented (
bind -> listen -> accepton server;connect -> sendall -> recvon client). - UDP is connectionless (
sendtoandrecvfrom). A UDP server uses a single socket for all clients and never usesselect.select().
- TCP is connection-oriented (
- Socket Port Reuse (
SO_REUSEADDR): Always addserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)beforebind()on TCP servers and proxies to avoidAddress already in useerrors when restarting. - Binary Struct Packing (
struct.Struct):- Format codes:
i(4-byte int),I(4-byte unsigned int),f(4-byte float),?(1-byte bool),cor1s(1-byte char asbytes),Xslike7s(X-byte string asbytes). - C Alignment Padding Rule: Never count bytes manually (
'c i'is 8 bytes due to 3 padding bytes;'i c'is 5 bytes;'i i c'is 9 bytes;'I I 1s'is 12 bytes;'7s6s'is 13 bytes). Always passpacker.sizetorecv(packer.size). - Null-Byte Padding Rule: Packing a shorter string like
b"FAIL"into a7sfield pads the trailing bytes with null bytes (b"FAIL\x00\x00\x00"). Always strip null bytes after unpacking:status = status_bytes.decode().strip('\x00').
- Format codes:
Part 2: Essential Building Blocks
import sys, struct, json, hashlib, zlib # 1. Command-Line Arguments (python3 script.py localhost 10000 input.txt) ip = sys.argv[1] port = int(sys.argv[2]) filename = sys.argv[3] # 2. Struct Packing & Unpacking packer = struct.Struct('i i 1s') packed_bytes = packer.pack(10, 25, b'+') a, b, raw_op = packer.unpack(packed_bytes) op = raw_op.decode().strip('\x00') # 3. Delimiter-Separated Payloads (':', ';', '|') numbers = [3, 7, 12, 18, 20] bet = 500 msg_bytes = (":".join(str(x) for x in numbers) + f":{bet}").encode() parts = [int(x) for x in msg_bytes.decode().split(":")] recv_nums, recv_bet = parts[:-1], parts[-1] # 4. Reading Text, JSON, and Binary Files with open("input.json", "r") as f: data = json.load(f) # 5. MD5 and CRC32 Checksums md5_hex = hashlib.md5(b"1:5:12:19:20").hexdigest() crc_int = zlib.crc32(b"1:5:12:19:20") Part 3: Master Network Templates (TCP, Select, UDP, TCP-UDP Proxy)
Template 1: Single-Client TCP Server & Client
# --- tcp_server.py --- import socket, sys ip, port = sys.argv[1], int(sys.argv[2]) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server: server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((ip, port)) server.listen(5) print(f"TCP Server listening on {ip}:{port}") while True: conn, addr = server.accept() with conn: print(f"Connected by {addr}") data = conn.recv(1024) if data: print("Received:", data.decode()) conn.sendall(b"Hello client") # --- tcp_client.py --- import socket, sys ip, port = sys.argv[1], int(sys.argv[2]) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client: client.connect((ip, port)) client.sendall(b"Hello server") print("Server replied:", client.recv(1024).decode()) Template 2: Multi-Client TCP Server with select.select()
# --- select_tcp_server.py --- import socket, select, sys ip, port = sys.argv[1], int(sys.argv[2]) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((ip, port)) server.listen(5) inputs = [server] print(f"Multi-client TCP Server running on {ip}:{port}...") while True: readable, _, _ = select.select(inputs, [], [], 1.0) for s in readable: if s is server: conn, addr = server.accept() print(f"[+] New client connected: {addr}") inputs.append(conn) else: data = s.recv(1024) if not data: print("[-] Client disconnected") inputs.remove(s) s.close() else: print(f"[<] Received: {data.decode()}") s.sendall(b"OK") Template 3: UDP Server & Client with Timeout
# --- udp_server.py --- import socket, sys sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((sys.argv[1], int(sys.argv[2]))) while True: data, client_addr = sock.recvfrom(1024) print(f"Received {data.decode()} from {client_addr}") sock.sendto(b"Hello Client", client_addr) # --- udp_client.py --- import socket, sys server_addr = (sys.argv[1], int(sys.argv[2])) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(2.0) try: sock.sendto(b"Hello Server", server_addr) data, _ = sock.recvfrom(1024) print("Received:", data.decode()) except (socket.timeout, ConnectionResetError): print("UDP Server did not respond!") finally: sock.close() Template 4: TCP-to-UDP Bridge Proxy
# --- tcp_udp_proxy.py --- # Usage: python3 tcp_udp_proxy.py <proxy_ip> <proxy_port> <server_ip> <server_port> import socket, select, struct, sys proxy_addr = (sys.argv[1], int(sys.argv[2])) server_addr = (sys.argv[3], int(sys.argv[4])) tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcp_sock.bind(proxy_addr) tcp_sock.listen(5) udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_sock.settimeout(2.0) packer = struct.Struct("i i c") inputs = [tcp_sock] while True: readable, _, _ = select.select(inputs, [], []) for s in readable: if s is tcp_sock: conn, addr = tcp_sock.accept() print("Client connected to proxy:", addr) inputs.append(conn) else: msg = s.recv(packer.size) if not msg: inputs.remove(s) s.close() continue udp_sock.sendto(msg, server_addr) result, _ = udp_sock.recvfrom(packer.size) val, zero, r_char = packer.unpack(result) s.sendall(packer.pack(val * 2, zero, r_char)) Part 4: 5 Complete Protocol Implementations
Implementation 1: Schedule & Seat Reservation Protocol (7s6s) + 50% Intercept Proxy
Sample screenings.txt:
Dune;Hall 1;17:30;5 Oppenheimer;Hall 2;19:00;3 Barbie;Hall 1;20:45;0 # --- reservation_server.py --- # Usage: python3 reservation_server.py <ip> <port> <screenings.txt> import socket, select, struct, sys, random, string ip, port, filename = sys.argv[1], int(sys.argv[2]), sys.argv[3] screenings = {} with open(filename, "r") as f: for line in f: line = line.strip() if line: title, hall, start_time, seats = line.split(";") screenings[f"{title};{start_time}"] = { "title": title, "hall": hall, "time": start_time, "seats": int(seats) } packer = struct.Struct("7s6s") server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((ip, port)) server.listen(5) inputs = [server] print(f"Server running on {ip}:{port}...") while True: readable, _, _ = select.select(inputs, [], []) for s in readable: if s is server: conn, addr = server.accept() print(f"[+] Client connected: {addr}") inputs.append(conn) else: data = s.recv(1024) if not data: print("[-] Client disconnected") inputs.remove(s) s.close() continue msg = data.decode().strip() print(f"[<] Received: {msg}") if msg == "GET_SCREENINGS": reply_str = "|".join( f"{v['title']};{v['hall']};{v['time']}" for v in screenings.values() ) s.sendall(reply_str.encode()) print(f"[>] Sent screenings: {reply_str}") else: if msg in screenings and screenings[msg]["seats"] > 0: screenings[msg]["seats"] -= 1 ticket_id = "".join(random.choices(string.ascii_uppercase + string.digits, k=6)) s.sendall(packer.pack(b"SUCCESS", ticket_id.encode())) print(f"[>] SUCCESS for {msg}. ID: {ticket_id} (Seats left: {screenings[msg]['seats']})") else: s.sendall(packer.pack(b"FAIL", b"000000")) print(f"[>] FAIL for {msg}.") # --- reservation_client.py --- # Usage: python3 reservation_client.py <ip> <port> <film_title> <start_time> import socket, struct, sys ip, port = sys.argv[1], int(sys.argv[2]) film = sys.argv[3] if len(sys.argv) > 3 else "Dune" time_str = sys.argv[4] if len(sys.argv) > 4 else "17:30" packer = struct.Struct("7s6s") with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client: client.connect((ip, port)) client.sendall(b"GET_SCREENINGS") print("[>] Sent: GET_SCREENINGS") screenings_raw = client.recv(1024).decode() print("[<] Available screenings:") for item in screenings_raw.split("|"): print(" -", item) buy_req = f"{film};{time_str}" client.sendall(buy_req.encode()) print(f"[>] Attempting to reserve: {buy_req}") resp_data = client.recv(packer.size) status_bytes, ticket_bytes = packer.unpack(resp_data) status = status_bytes.decode().strip('\x00') ticket_id = ticket_bytes.decode().strip('\x00') print(f"[<] Server Result: {status}, Ticket ID: {ticket_id}") # --- intercept_proxy.py --- # Usage: python3 intercept_proxy.py <proxy_ip> <proxy_port> <server_ip> <server_port> import socket, struct, sys, random proxy_addr = (sys.argv[1], int(sys.argv[2])) server_addr = (sys.argv[3], int(sys.argv[4])Source:https://dev.to/unnobatroo/python-3-standard-library-socket-programming-cookbook-tcp-udp-selectselect-struct-packing-4hjj PreviousMonitoring Perpetual Futures Liquidation Risk in Python: Mark Price, Margin State, and Data FreshnessNextSignal2Speech: we tested a real EEG board on two people, and it didn’t work (Update 5)
Related posts

Asahi Linux Moves from MIT to GPL Licensing, Expands M3 Support
0Linuxiac
How to Use Customer Photos and Testimonials on Your Website Without It Looking Messy
0dev.to Design
The Difference Between a Website That Looks Good and One That Actually Sells
0dev.to Design

.NET 11 Unpacked: Why I'm Recommending STS This Time
0dev.to C#
This week in Cursor + .NET — 7 rules (week ending November 15, 2026)
0dev.to C#

How do you move RunPod training jobs over to Nodus?
0dev.to Tutorial