4.3.28 · D5 · HinglishComputer Networks

Question bankSocket programming — TCP server - client, UDP server - client in Python

2,906 words13 min read↑ Read in English

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

Neeche har answer ek reason hai, na ki seedha yes/no — kyunki exam ya interview mein reason hi marks laata hai.


Pehle, woh vocabulary jo ye traps assume karti hai

Neeche ki zyaadatar traps chaar shabdon par tikti hain. Inhe hum yahaan, is page par hi define karte hain, taaki kisi trap ko samajhne ke liye kahin aur jaana na pade.


Systems picture: ek byte stream kaise fragment aur coalesce hota hai

Almost har TCP trap ("apna framing add karo", "loop until b''") ek ek hidden mechanism se aati hai: kernel send/receive buffers. Is diagram ko ek baar samajh lo aur traps obvious ho jaayengi.


Ek running narrative: ek client ka connect → sendall cycle

Traps se pehle, yeh concrete story ek baar walk karo. Yeh woh scaffold hai jisme har trap fit hoti hai.


True ya false — justify karo

TCP guarantee karta hai ki client par ek send exactly ek recv server par ban jaata hai.
False. send sirf bytes ko kernel ke send buffer mein copy karta hai; kernel unhe apne schedule par segments mein slice karta hai, toh ek send kai recvs mein split ho sakta hai ya kai sends ek mein merge ho sakte hain. Boundaries tumhe add karni hogi — dekho Message framing / length-prefix protocol.
UDP guarantee karta hai ki ek sendto exactly ek recvfrom ban jaata hai (agar woh pahunche toh).
True. UDP message boundaries preserve karta hai: har datagram ek self-contained unit hai jise kernel kabhi split ya merge nahi karta. Woh lost, duplicated, ya reordered ho sakta hai, lekin uske contents poore pahunchte hain ya bilkul nahi.
socket() se return hota listening socket wahi object hai jis par tum client data padhte aur likhte ho.
False. TCP mein, accept ek naya per-client socket (conn) return karta hai jo poore 4-tuple se named hota hai; original listening socket passive rehta hai taaki aur clients accept kar sake. conn par read/write karo, listener par nahi.
b'' return karna matlab peer ke paas is baar kehne ke liye kuch nahi tha.
False. Empty bytes EOF signal hai: peer ne FIN bheja hai aur woh aur kabhi nahi bhejeha. "Abhi kuch nahi" woh block karta. Apna loop break karo, warna woh forever busy-spin karta rahega.
sendall aur send interchangeable hain.
False. send tumhare buffer ka sirf part copy kar sakta hai (actually queued count return karta hai); sendall loop karta hai jab tak har byte queued na ho jaaye (ya raise kare). Kuch bytes se zyada kisi bhi cheez ke liye, sendall prefer karo.
Client ko baat karne se pehle hamesha ek port par bind karna chahiye.
False. Client normally bind skip karta hai; connect/sendto par OS automatically ek ephemeral port assign karta hai (ek temporary high-numbered port jo baad mein recycle ho jaata hai). Sirf woh side jo doosre dhundhte hain — server — ko fixed, known port chahiye. Dekho Ports and IP addressing.
UDP socket par connect() call karna server ke saath handshake karta hai.
False. UDP connect koi network handshake nahi karta — yeh sirf locally default peer fix karta hai taaki tum sendto/recvfrom ki jagah send/recv use kar sako. Machine se zero packets jaate hain. Compare karo TCP three-way handshake se.
listen(5) ka matlab hai server kul milaa ke zyaada se zyaada 5 clients handle kar sakta hai.
False. 5 backlog hai, un connections ke liye waiting-room depth jo abhi accept nahi hue. Jaise tum unhe accept aur process karte ho, aur queue ho sakte hain. Yeh pending connections cap karta hai, total ya concurrent nahi.
Do sockets kabhi ek hi local port number ek saath use nahi kar sakte.
False. Ek connection poore 4-tuple (local IP, local port, remote IP, remote port) se named hota hai. Kai clients server ke single port 9000 par aate hain; har conn remote IP/port mein differ karta hai, toh woh coexist karte hain.
SO_REUSEADDR do servers ko same port par simultaneously actively serve karne deta hai.
False (mostly). SO_REUSEADDR mainly tumhe ek port par bind karne deta hai jo pichle instance ki TIME_WAIT mein stuck hai, taaki restart "Address already in use" se fail na ho. Yeh do live listeners ko address share karne nahi deta — woh ek alag option hai (neeche SO_REUSEPORT edge case dekho). Dekho TIME_WAIT and SO_REUSEADDR.

Error dhundho

c.send("hello") jahan c ek connected TCP socket hai.
Sockets bytes carry karte hain, str nahi. Yeh TypeError raise karta hai. Fix: c.send(b"hello") ya c.send("hello".encode()), aur receiving side par .decode().
UDP server code jo s.listen(5) call karta hai phir conn, addr = s.accept().
listen/accept TCP ke hain (connection setup). UDP connectionless hai — inhe hata do aur recvfrom/sendto use karo, jo har call mein address carry karte hain.
TCP server jo directly listening socket s par s.recv(1024) call karta hai.
Tumhe accept se returned socket (per-client conn) par recv karna chahiye, listening socket par nahi. Listener sirf connections produce karta hai; woh koi application data carry nahi karta.
Ek loop while True: data = conn.recv(1024) jo data process karta hai lekin kabhi b'' check nahi karta.
Jab peer close karta hai (FIN), recv har future call par b'' return karta hai aur loop busy-spin karta hai. if not data: break add karo ise EOF treat karne ke liye.
Client b"PING" bhejta hai phir turant conn.recv karta hai exactly b"PONG" expect karte hue, yeh assume karte hue ki poora reply ek call mein aayega.
Kernel reply pieces mein deliver kar sakta hai. Tumhe recv loop karna hoga aur accumulate karna hoga jab tak tumhara framing nahi kehta ki message complete hai (length-prefix ya delimiter). Dekho Message framing / length-prefix protocol.
Server s.bind(('127.0.0.1', 9000)) karta hai lekin client machine ke LAN IP se connect karta hai.
127.0.0.1 (loopback) par bind karna sirf same machine se connections accept karta hai. Doosre hosts se accept karne ke liye, '0.0.0.0' (sabhi IPv4 interfaces) ya specific LAN IP par bind karo.
Same UDP socket reuse karte hue client A ko sendto, phir recvfrom ke addr ki jagah hard-coded address par blindly reply sendto.
Tum galat host ko reply karoge. UDP mein tumhe exactly wahi addr par wapas bhejna hoga jo recvfrom ne return kiya, kyunki koi connection tumhare liye peer yaad nahi rakhta.

"Why" questions

TCP server ko listen aur accept dono kyun chahiye jab client ko dono ki zaroorat nahi?
listen socket ko passive mark karta hai (woh waiting room kholta hai) aur accept us queue se ek connection nikalta hai, ek dedicated socket return karta hai. Client active hai — woh connect se dial karta hai, jise koi queue nahi chahiye.
Basic flow mein UDP mein accept/connect/listen kyun nahi hote?
Koi connection setup nahi hoti. Har datagram self-addressed hai, toh destination har sendto ke andar travel karta hai na ki ek baar handshake se establish hota hai.
accept ek naya socket kyun return karta hai listener reuse karne ki jagah?
Taaki listener doosre clients ko accept karta rahe jabki naya socket is ek conversation ko handle kare. Ek listener → kai per-client sockets, har ek ek distinct 4-tuple.
recv(1024) mein 1024 fixed size ki jagah maximum kyun hai?
recv bas jo bhi bytes abhi kernel receive buffer mein hain unhe drain karta hai, 1024 tak. Woh kam return kar sakta hai (buffer mein kam tha) — number ek buffer cap hai, kabhi message length nahi.
DNS lookups, gaming, aur video calls jaise cheezoon ke liye UDP prefer kyun karte hain?
Inhe perfect delivery se zyaada low latency chahiye — ek late packet ek lost packet se bura hai, aur koi handshake tax ya retransmit stall nahi hai. Dekho UDP vs TCP tradeoffs aur DNS.
Ek TCP server ko jaldi restart karne par "Address already in use" kyun milta hai?
Abhi-closed connection TIME_WAIT mein baitha hai apna 4-tuple hold kiye taaki late stray packets kisi naye connection ko corrupt na kar sakein. SO_REUSEADDR OS ko batata hai ki us lingering state par bind karna safe hai. Dekho TIME_WAIT and SO_REUSEADDR.
Ek single-threaded server jo sirf accept→handle→accept loop karta hai clients ko starve kyun kar sakta hai?
Jab woh ek client handle kar raha hota hai, doosre backlog queue mein un-accepted baithte hain. Ek saath kai serve karne ke liye tumhe select / asyncio for concurrent servers ya threads/processes chahiye.

Edge cases

Kya hota hai agar ek UDP client "A", "B", "C" bhejta hai aur ek network mein kho jaata hai?
Server sirf survivors padhta hai, possibly out of order — UDP detect, retransmit, ya reorder nahi karta. Agar yeh matter karta hai toh khud sequence numbers/acks add karo.
Ek TCP client agar teen sends "A","B","C" back-to-back karta hai toh server kya padhta hai?
Possibly ek recv b"ABC" return karta hai, ya b"AB" phir b"C" jaisi split — kernel ne unhe adjacent buffer kiya bina kisi boundaries ke. Teen messages recover karne ka ek hi tarika hai: framing.
Kya hota hai agar tum ek TCP socket par recv karo jiska peer bina cleanly close kiye crash ho gaya ho?
Koi FIN na bheja gaya hone ki wajah se, tum indefinitely block ho sakte ho, ya eventually OS keepalives ke depending par ConnectionResetError/timeout mil sakta hai. Dead peers detect karne ke liye timeouts ya application-level heartbeats set karo.
Server ko port 0 par bind karna kya karta hai?
OS tumhare liye ek free ephemeral port choose karta hai; ise getsockname() se wapas padho. Tests ke liye handy hai, lekin clients ko phir batana hoga ki kaunsa port choose hua.
Kya UDP localhost par truly reliable hai?
Loopback rarely drop karta hai, jo tumhe UDP trust karne ke liye tempt karta hai — lekin wahi code ek real network par drop, duplicate, aur reorder karega. Kabhi localhost behaviour ko convince mat hone do ki UDP reliable hai.
Kya hota hai agar server kabhi accept na kare lekin clients backlog se aage connect karte rahen?
Jab backlog queue full ho jaati hai, naye connection attempts refuse ya drop ho jaate hain (client timeout ya connection-refused dekhta hai). Waiting room finite hai.
SO_REUSEADDR aur SO_REUSEPORT mein kya difference hai, aur yeh kyun matter karta hai?
SO_REUSEADDR mainly tumhe TIME_WAIT mein lingering port par rebind karne deta hai (jaldi restart karo); yeh do live listeners ko same port grant nahi karta. SO_REUSEPORT (Linux) actually kai sockets ko same IP:port par simultaneously bind karne deta hai, aur kernel incoming connections ko unke beech load-balance karta hai — multi-process concurrent servers ke liye asli tool. Dono ko confuse karna ek classic interview trap hai.
IPv6 server socket bind karna dual-stack host par IPv4 se kaise differ karta hai?
IPv6 wildcard '::' hai (sabhi IPv6 interfaces), IPv4 ke '0.0.0.0' ka analogue. Kai dual-stack systems par '::' par bind kiya socket IPv4 clients ko bhi IPv4-mapped addresses via accept karta hai (::ffff:1.2.3.4 ke roop mein dikhta hai) jab tak IPV6_V6ONLY option set na ho. Toh '::' us flag par depending IPv4 cover kar bhi sakta hai ya nahi — kabhi assume mat karo; agar tumhe parwah hai toh IPV6_V6ONLY explicitly set karo.
Recall Is page close karne se pehle ek one-line self-test

Zyaban par bolo: TCP = stream (kernel buffers, no boundaries → frame it), recv b'' = FIN/EOF; UDP = datagrams, boundaries kept, may drop/reorder; client ko ephemeral port milta hai, rarely binds; accept ek naya socket janamta hai jo 4-tuple se named hai; REUSEADDR ≠ REUSEPORT. Agar koi clause tumhe surprise kare, woh trap upar jaake dubara dekho.


Related: UDP vs TCP tradeoffs · Message framing / length-prefix protocol · TCP three-way handshake · Ports and IP addressing · TIME_WAIT and SO_REUSEADDR · select / asyncio for concurrent servers · DNS