4.3.28 · D3 · HinglishComputer Networks

Worked examplesSocket programming — TCP server - client, UDP server - client in Python

2,710 words12 min read↑ Read in English

4.3.28 · D3 · Coding › Computer Networks › Socket programming — TCP server - client, UDP server - clien

Tumne parent note mein calls already dekh li hain the parent note. Ab hum unhe stress-test karenge: "do programs ek socket pe baat karein to actually kya ho sakta hai" ke har quadrant ko. Loss, reordering, partial reads, closed peers, wrong protocol — har ek ka apna worked example hai taaki tum koi aisa case kabhi na dekho jise tumne pehle na dekha ho.


The scenario matrix

Neeche har worked example us cell ke saath tagged hai jise woh cover karta hai. Pehle table padho — yeh poora test surface hai.

# Cell (case class) Protocol Yahan kya alag hai Example
A Happy path, one send = one recv TCP Baseline, kuch bhi weird nahi Ex 1
B Coalescing — bahut saare sends, ek recv TCP Stream mein koi message boundaries nahi Ex 2
C Splitting — ek send, bahut saare recvs TCP Ek bada send pieces mein aata hai Ex 3
D Peer closedrecv returns b'' TCP Degenerate/EOF input Ex 4
E Boundaries preserved UDP Ek sendto = ek recvfrom Ex 5
F Loss + reorder — the ugly case UDP Packets gayab ho jaate hain / ulte-seedhe aate hain Ex 6
G Framing fix (length prefix) TCP Real-world word problem Ex 7
H Wrong protocol / exam twist mixed listen on UDP, str not bytes, no bind Ex 8

Cells A–D TCP ke behaviour ko exhaust karte hain, E–F UDP ke, G standard fix dikhata hai, H exam trap collection hai. Saath mein yeh matrix ko cover karte hain.

Figure — Socket programming — TCP server - client, UDP server - client in Python

Example 1 — Cell A: the happy path (TCP)

  1. Client OS ko 5 bytes deta hai. Yeh step kyun? b"hello" ASCII bytes h e l l o = 5 bytes hai. sendall internally loop karta hai jab tak saare 5 bytes network ke liye queue nahi ho jaate.
  2. Server "up to 1024" maangta hai. Yeh step kyun? recv(1024) matlab hai "jo bhi ready ho woh de do, zyada se zyada 1024 bytes". Kyunki sirf 5 bytes in flight hain aur woh saath aate hain, yeh saare 5 return karta hai.
  3. Result: data == b"hello", len(data) == 5.

Example 2 — Cell B: coalescing (TCP)

  1. TCP ek byte stream hai, message queue nahi. Yeh step kyun? Kernel ko allowed hai ki outgoing bytes ko jaane se pehle ek segment mein merge kare. "AA" aur "BB" ke beech koi marker nahi hai.
  2. Server ka ek recv(1024) jo bhi available hai woh sab scoop kar leta hai. Yeh step kyun? Jab recv run hota hai tab saare 6 bytes already receive buffer mein baithe ho sakte hain, to yeh unhe saath return kar deta hai.
  3. Result: ek possible (localhost pe bahut common) outcome hai data == b"AABBCC", len == 6.
Figure — Socket programming — TCP server - client, UDP server - client in Python

Example 3 — Cell C: splitting (TCP)

  1. recv(1024) kabhi bhi 1024 bytes se zyada return nahi kar sakta. Yeh step kyun? Humne max 1024 maanga. 3000 bytes ek call mein nahi aa sakte.
  2. Har call up to 1024 return karta hai, jo bhi currently buffered hai. Yeh step kyun? Network delivery segment size se chunked hoti hai; receiver jo hai woh drain karta hai. Ek plausible sequence hai 1024, 1024, 952 — teen calls jo 3000 pe sum karte hain. Exact split guaranteed nahi hai; sirf total aur order hain.
  3. Loop tab tak jab tak 3000 bytes collect na ho jaayein (ya b'' na mile). Yeh step kyun? Tumhe padhte rehna hoga — bade data ke liye ek recv almost kabhi bhi poora message nahi hota.

Example 4 — Cell D: the degenerate input, recv returns b'' (TCP)

  1. Ek clean close peer ko ek FIN bhejta hai. Yeh step kyun? close() OS ko kehta hai "mere se aur bytes nahi". Receiver ka stream apne end pe pahunch jaata hai.
  2. Ek closed stream pe recv empty bytes object b'' return karta hai. Yeh step kyun? b'' socket ka tarika hai EOF kehne ka — end of file, matlab peer ne hang up kar liya. Yeh "client ne kuch nahi bheja" nahi hai.
  3. Server ko loop break karna chahiye. Yeh step kyun? Agar tum b'' ke liye test nahi karte, to tum b'' lete hue forever loop karte ho aur CPU spin karte ho.
while True:
    data = conn.recv(1024)
    if data == b'':      # ya: if not data
        break            # peer closed — EOF
    conn.sendall(data)

Example 5 — Cell E: UDP preserves boundaries

  1. Har sendto ek self-contained datagram hai. Yeh step kyun? UDP messages carry karta hai, stream nahi. "AA" aur "BB" ke beech ki boundary packet structure mein baked in hai.
  2. Har recvfrom exactly ek datagram return karta hai. Yeh step kyun? Tum do UDP packets ko ek read mein merge nahi kar sakte, aur ek ko do reads mein split nahi kar sakte. Ek packet ↔ ek recvfrom.
  3. Result (no loss): teen calls b"AA", b"BB", b"CC" return karte hain — kabhi b"AABBCC" nahi.
Figure — Socket programming — TCP server - client, UDP server - client in Python

Example 6 — Cell F: the ugly case, loss aur reorder (UDP)

  1. UDP koi delivery guarantee nahi deta. Yeh step kyun? Koi handshake nahi, koi ack nahi, koi retransmit nahi. Load ke neeche ek router simply packet 3 discard kar deta hai.
  2. UDP koi ordering guarantee nahi deta. Yeh step kyun? Packets alag paths le sakte hain; 4 2 se pehle aa sakta hai. Boundaries abhi bhi preserved hain (har read ek poora packet hai), lekin sequence nahi.
  3. Possible received sequence: 1, 4, 2, 5 — chaar datagrams, ek lost, do swapped.

Example 7 — Cell G: real-world fix, length-prefix framing (TCP)

  1. Payload ko uski length ke 4-byte big-endian integer se prefix karo. Yeh step kyun? Kyunki TCP mein koi boundaries nahi hain (Ex 2 & 3), receiver ko ek explicit "N bytes aa rahe hain" chahiye. 11 big-endian packed hai \x00\x00\x00\x0b.
  2. Wire bytes = 4 (header) + 11 (payload) = 15 bytes. Yeh step kyun? Receiver pehle exactly 4 bytes padhta hai, N = 11 decode karta hai, phir recv loop karta hai jab tak usne 11 aur collect nahi kar liye.
  3. Receiver algorithm: 4 padho → N lo → N padho. Ab boundaries recover ho jaati hain chahe TCP ne kuch bhi chunk kiya ho.
import struct
def send_msg(sock, payload):
    header = struct.pack('>I', len(payload))  # 4-byte big-endian length
    sock.sendall(header + payload)
 
def recv_exact(sock, n):
    buf = b''
    while len(buf) < n:
        chunk = sock.recv(n - len(buf))
        if chunk == b'':               # EOF (Ex 4!)
            raise ConnectionError("peer closed mid-message")
        buf += chunk
    return buf
 
def recv_msg(sock):
    n = struct.unpack('>I', recv_exact(sock, 4))[0]
    return recv_exact(sock, n)

Example 8 — Cell H: exam twists aur wrong-protocol traps

(a) UDP with listen/accept:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.listen(5)      # ???
  1. SOCK_DGRAM UDP hai; UDP connectionless hai. Yeh step kyun? listen/accept connections set up karte hain, jo UDP ke paas nahi hote. Yeh OSError raise karta hai. UDP sirf bind karta hai phir recvfrom/sendto.

(b) Ek str bhejna:

c.send("hi")     # ???
  1. Sockets bytes carry karte hain, str nahi. Yeh step kyun? send ko bytes-like object chahiye → yeh TypeError raise karta hai. Fix: c.send(b"hi") ya "hi".encode().

(c) Client jo bind karta hai vs jo nahi karta:

c.connect(('127.0.0.1', 9000))   # iske pehle koi bind nahi
  1. Client ko bind ki zaroorat nahi hoti. Yeh step kyun? connect pe OS automatically ek ephemeral port assign kar deta hai (dekho Ports and IP addressing). Sirf server ko, jishe doosre find karte hain, ek fixed bind chahiye.

(d) Fast restart, no SO_REUSEADDR:

s.bind(('127.0.0.1', 9000))   # pichla server close hone ke baad
  1. OSError: Address already in use raise ho sakta hai. Yeh step kyun? Purana socket TIME_WAIT mein linga rehta hai (dekho TIME_WAIT and SO_REUSEADDR). bind se pehle SO_REUSEADDR set karne se tum port immediately reclaim kar sakte ho.


Flashcards

TCP mein, teen sendall calls kitne recv calls ke roop mein aa sakti hain?
Koi bhi number — ek merged recv bhi ho sakta hai (stream coalescing).
TCP mein recv() ka b'' return karna kya matlab hai?
Peer ne connection close kar diya (EOF).
Kya UDP datagrams merge ya split karta hai?
Kabhi nahi — ek sendto exactly ek recvfrom ke barabar hota hai.
TCP pe 3000 bytes padhne ke liye recv(1024) ke minimum kitne calls?
3 (3000/1024 ka ceil).
Length-prefix protocol TCP pe message boundaries kaise recover karta hai?
Ek fixed header padho jo N deta hai, phir exactly N payload bytes padho.
Kaunsa side normally bind skip karta hai?
Client — OS usse ek ephemeral port assign karta hai.