Network Programming
Network programming means building programs that communicate with other programs over a network. If your app talks to a website, an API, a database server, a chat service, or another machine, you are doing network programming.
This topic can feel scary at first, but the core idea is simple: one side sends data, another side receives data, and both sides follow a protocol (set of rules).
In this chapter, you will learn from basic concepts to practical patterns used in real projects.
Networking Basics
Section titled “Networking Basics”Before writing socket or HTTP code, understand these fundamentals. They help you debug faster and reason about how data moves.
IP Addresses
Section titled “IP Addresses”An IP address uniquely identifies a device on a network.
- IPv4:
192.168.1.1 - IPv6:
2001:db8::1
Think of an IP address as a home address for a device.
- If you send data to the wrong IP, it goes to the wrong machine.
127.0.0.1(orlocalhost) means “this same computer.”
A port identifies a specific process/service on a machine.
Examples:
80→ HTTP443→ HTTPS22→ SSH
Think of a port as a room number inside a building.
- IP identifies the building (device)
- Port identifies the room (service/app)
Key idea:
IP Address = DevicePort = Application inside deviceSockets
Section titled “Sockets”A socket is an endpoint for communication between two machines.
It combines:
(IP Address + Port)When two sockets connect, data can flow in both directions.
Protocols: TCP and UDP
Section titled “Protocols: TCP and UDP”Protocols define how data is sent.
TCP (Transmission Control Protocol)
Section titled “TCP (Transmission Control Protocol)”- reliable delivery
- packets arrive in correct order
- connection-oriented
- slower than UDP, but safer
Use TCP for:
- web apps
- APIs
- logins
- payments
UDP (User Datagram Protocol)
Section titled “UDP (User Datagram Protocol)”- very fast
- no delivery guarantee
- no strict ordering
- connectionless
Use UDP for:
- live voice/video
- multiplayer games
- telemetry where speed matters more than perfect reliability
Client-Server Flow
Section titled “Client-Server Flow”Most internet communication follows this model. The client asks, the server answers.
Examples:
- Browser (client) requests a webpage from a web server.
- Mobile app (client) requests user data from an API server.
Socket Programming in Python
Section titled “Socket Programming in Python”Socket programming gives you low-level control of network communication.
Python provides the built-in socket module, which is a great way to understand the core mechanics behind networking.
Socket Lifecycle (TCP)
Section titled “Socket Lifecycle (TCP)”- Create socket
- Bind socket to IP + port (server side)
- Listen for connections
- Accept a client
- Send/receive bytes
- Close socket
This lifecycle appears in many real systems, even if frameworks hide details.
TCP vs UDP
Section titled “TCP vs UDP”Both are useful. Choose based on project needs:
- choose TCP for correctness and reliability
- choose UDP for low-latency streaming-style workloads
TCP Communication Flow
Section titled “TCP Communication Flow”TCP Server Example (Beginner Version)
Section titled “TCP Server Example (Beginner Version)”import socket
HOST = "127.0.0.1"PORT = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((HOST, PORT))server.listen()
print(f"Server running on {HOST}:{PORT}")
while True: client_socket, client_addr = server.accept() print(f"Connected by {client_addr}")
data = client_socket.recv(1024) message = data.decode("utf-8") print("Client says:", message)
reply = "Hello from server" client_socket.send(reply.encode("utf-8")) client_socket.close()Explanation
Section titled “Explanation”AF_INETchooses IPv4SOCK_STREAMmeans TCPbind()attaches server to host and portlisten()starts waiting for clientsaccept()returns a new socket for that clientrecv()receives bytessend()sends bytes
TCP Client Example
Section titled “TCP Client Example”import socket
HOST = "127.0.0.1"PORT = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect((HOST, PORT))
client.send("Hello server".encode("utf-8"))
response = client.recv(1024)print("Server says:", response.decode("utf-8"))
client.close()Try it:
- Run server file first.
- Run client file in another terminal.
- Observe request/response messages.
UDP Example
Section titled “UDP Example”UDP Server
Section titled “UDP Server”import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server.bind(("localhost", 8080))
while True: data, addr = server.recvfrom(1024) print("Received:", data.decode())
server.sendto(b"Hello UDP Client", addr)UDP Client
Section titled “UDP Client”import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(b"Hello UDP Server", ("localhost", 8080))
data, _ = client.recvfrom(1024)print(data.decode())In UDP there is no connect() handshake like TCP. You send datagrams directly.
HTTP Concepts
Section titled “HTTP Concepts”HTTP is the protocol used by browsers, APIs, and many web services.
When you open a website, your browser sends an HTTP request and receives an HTTP response.
Request-Response Cycle
Section titled “Request-Response Cycle”HTTP Request Structure
Section titled “HTTP Request Structure”GET /index.html HTTP/1.1Host: example.comUser-Agent: browserThis request says: “Please send me /index.html from this host.”
HTTP Response Structure
Section titled “HTTP Response Structure”HTTP/1.1 200 OKContent-Type: text/html
<html>...</html>200 OK means success. The body contains the actual data (HTML, JSON, image, etc.).
HTTP Methods
Section titled “HTTP Methods”- GET → Retrieve data
- POST → Send data
- PUT → Update data
- DELETE → Remove data
In REST APIs, these methods map to create/read/update/delete operations.
Status Codes
Section titled “Status Codes”200→ Success201→ Created successfully400→ Bad request from client401→ Unauthorized403→ Forbidden404→ Not Found500→ Server Error301→ Redirect
Using the requests Library
Section titled “Using the requests Library”The requests library makes HTTP calls easy and readable.
It is one of the most used Python libraries in backend and automation work.
Installation
Section titled “Installation”pip install requestsGET Request
Section titled “GET Request”import requests
response = requests.get("https://api.github.com", timeout=10)
print(response.status_code)print(response.json())Use timeout so your program does not hang forever if a server is slow.
POST Request
Section titled “POST Request”import requests
data = {"username": "sahil", "password": "1234"}
response = requests.post("https://httpbin.org/post", json=data)
print(response.json())Use json=data when the API expects JSON payload.
Headers
Section titled “Headers”headers = { "Authorization": "Bearer token", "Content-Type": "application/json"}
response = requests.get("https://api.example.com", headers=headers)Headers are metadata (auth token, content type, language, etc.).
Handling Errors
Section titled “Handling Errors”import requests
response = requests.get("https://api.example.com")
if response.status_code == 200: print(response.json())else: print("Error:", response.status_code)Better production-style handling:
import requests
try: response = requests.get("https://api.example.com", timeout=10) response.raise_for_status() # raises HTTPError for 4xx/5xx data = response.json() print(data)except requests.exceptions.Timeout: print("Request timed out")except requests.exceptions.RequestException as exc: print("Request failed:", exc)This prevents crashes and gives better diagnostics.
JSON and APIs
Section titled “JSON and APIs”APIs usually send/receive JSON.
JSON Example
Section titled “JSON Example”{ "name": "Sahil", "age": 21}Python Handling
Section titled “Python Handling”data = response.json()print(data["name"])When parsing JSON from APIs:
- validate expected keys
- handle missing fields safely
- do not assume every response has same shape
Example:
user = response.json()name = user.get("name", "Unknown")print(name)Concurrency in Networking
Section titled “Concurrency in Networking”Real servers serve many clients at the same time. If you handle one client at a time, other users wait.
Common concurrency options:
- threads (easy to start)
- processes (for CPU-heavy work)
- async I/O (great for many network waits)
Threaded Server Example
Section titled “Threaded Server Example”import socketimport threading
def handle_client(client_socket): data = client_socket.recv(1024) client_socket.send(b"OK") client_socket.close()
server = socket.socket()server.bind(("localhost", 8080))server.listen()
while True: client, addr = server.accept() thread = threading.Thread(target=handle_client, args=(client,)) thread.start()This approach is simple but can consume many resources for huge traffic.
Threading Flow
Section titled “Threading Flow”Async Networking with asyncio
Section titled “Async Networking with asyncio”Async is useful when tasks spend most time waiting on network I/O.
Instead of blocking one thread per connection, async lets one event loop manage many connections efficiently.
Async Example
Section titled “Async Example”import asyncio
async def main(): print("Start") await asyncio.sleep(2) print("End")
asyncio.run(main())Real-world async networking usually uses libraries like aiohttp, httpx (async mode), or async web frameworks.
Async Flow
Section titled “Async Flow”DNS and URL Flow
Section titled “DNS and URL Flow”Before your request reaches a server, DNS translates domain names to IP addresses.
Example:
- You request
https://example.com - DNS returns the server IP
- TCP/TLS connection is created
- HTTP request is sent
- Server sends response
Understanding this helps when debugging “it works on one network but not another” issues.
Timeouts, Retries, and Reliability
Section titled “Timeouts, Retries, and Reliability”Network calls fail in real life. Servers go down, packets drop, and latency spikes happen.
Always design for failure:
- set timeouts
- add retries for temporary errors
- log failures clearly
Simple retry example:
import timeimport requests
url = "https://api.example.com/health"
for attempt in range(3): try: r = requests.get(url, timeout=5) r.raise_for_status() print("Service is healthy") break except requests.exceptions.RequestException: if attempt == 2: print("Service check failed after retries") else: time.sleep(1)Security Basics
Section titled “Security Basics”- Secure version of HTTP
- Uses SSL/TLS encryption
Never send passwords or tokens over plain HTTP in real applications.
Common Risks
Section titled “Common Risks”- Man-in-the-middle attack
- Data interception
- Injection attacks
- weak authentication
- leaking secrets in logs
Best Practices
Section titled “Best Practices”- Always use HTTPS
- Validate inputs
- Use authentication tokens
- never hardcode secrets in source code
- rate-limit sensitive endpoints
- sanitize and log safely
Real-World Applications
Section titled “Real-World Applications”Network programming is used in:
- Web servers (Django, Flask)
- APIs
- Chat applications
- Multiplayer games
- Microservices
Also used in:
- IoT devices
- payment gateways
- cloud monitoring systems
Common Beginner Mistakes
Section titled “Common Beginner Mistakes”- forgetting
encode()/decode()with sockets - not setting timeouts on HTTP calls
- assuming network requests always succeed
- testing only on localhost and ignoring real network behavior
- mixing business logic and networking logic in one large function
From Basic to Advanced Learning Path
Section titled “From Basic to Advanced Learning Path”- Build simple TCP client/server on localhost
- Build UDP echo app
- Use
requeststo call public APIs - Add error handling and retries
- Build threaded server for multiple clients
- Learn async networking for high concurrency
- Add authentication, logging, and observability
Quick Practice Tasks
Section titled “Quick Practice Tasks”- Create an echo server: whatever client sends, server returns back.
- Build a mini HTTP API checker that prints status and response time.
- Add timeout + retry to your API checker.
- Build a tiny chat app using sockets (single room).
These projects make networking concepts stick quickly.