Recall warm-up
- What four pieces of information uniquely identify a connected TCP socket?
Stuck? Peek at 4.3.2 TCP 3-way handshake, connection termination & state machine
- 3-way handshake:
SYN(seq=x) → SYN+ACK(seq=y, ack=x+1) → ACK(seq=x+1, ack=y+1). - Seq consumption:
SYN = +1,FIN = +1,Pure ACK = 0,Data(L) = +L(full connection advances byD + 2). - Teardown states: Active closer goes
FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT (2·MSL) → CLOSED; Passive closer goesCLOSE-WAIT (half-close) → LAST-ACK → CLOSED.
- 3-way handshake:
- Which packet in the TCP 3-way handshake is triggered when a client application calls connect()?
Stuck? Peek at 4.1 Transport basics: process-to-process delivery, ports, sockets & multiplexing
- Delivery: Network Layer = host-to-host; Transport Layer = process-to-process.
- Port number = 16 bits (0–65,535): Well-known
0–1023, Registered1024–49151, Ephemeral49152–65535. - Demultiplexing: UDP uses 2-tuple
(DstIP, DstPort); TCP uses 4-tuple(SrcIP, SrcPort, DstIP, DstPort). - UDP (Foundation) = 8-byte header, connectionless, best-effort; TCP = connection-oriented, reliable, flow + congestion controlled.
- Does a UDP server need to call listen() or accept() before receiving datagrams?
Stuck? Peek at 1.1.1 Why layer: protocol, service, interface, peers
- Layer: one job in the stack; serves the layer above, uses the layer below.
- Protocol: rules between peers (same layer, different machines): format, meaning, behaviour.
- Service: what a layer does for the layer above. Interface: how the layer above asks for it.
- Peer talk is logical; the real path is down → link → up.
- Layering = modularity + reuse − some overhead.
The Hook
Every networked program you have ever used — a web browser, an SSH client, a multiplayer game, or a database server — talks to the Operating System's TCP/IP stack through a small set of C system calls introduced in 4.2BSD Unix in 1983: the Berkeley Socket API.
GATE loves asking two exact questions about sockets: (1) What is the exact chronological sequence of system calls on the server vs the client, and (2) which call actually triggers the 3-way handshake and returns a brand-new socket descriptor?
Predict First
A web server binds to port 80 and calls listen(). When 500 clients simultaneously connect to port 80, does the server read all 500 clients' requests from that single listening socket?
No! The original socket passed to bind() and listen() is only a welcome (listening) socket! Each time a client finishes the 3-way handshake, the server's call to accept() returns a brand-new connected socket descriptor dedicated to that specific client's 4-tuple, leaving the welcome socket free to accept the next client!
Core Concept
The 7 Core Socket System Calls (Primitives)
Let's trace what each system call does inside the operating system kernel:
socket(domain, type, protocol): Creates a new communication endpoint in the OS kernel and returns an integer socket descriptor (e.g.,SOCK_STREAMfor TCP,SOCK_DGRAMfor UDP).bind(sockfd, local_addr, addrlen): Assigns a local (IP address, Port number) to the socket. Mandatory on servers (so clients know which well-known port to contact); normally omitted on clients (the OS automatically assigns an ephemeral port duringconnect()).listen(sockfd, backlog): (TCP Server only) Marks the bound socket as a passive (welcome) socket that will accept incoming SYN requests, and allocates a kernel queue of sizebacklogfor pending connections.connect(sockfd, serv_addr, addrlen): (Client) Initiates the active open! For TCP, it sends theSYNsegment and blocks until the server'sSYN-ACKarrives (completing the client side of the 3-way handshake).accept(listenfd, cli_addr, addrlen): (TCP Server only) Dequeues the next completed 3-way handshake from the listen queue (blocks if the queue is empty) and returns a BRAND-NEW connected socket descriptor for that specific client!send() / recv()(orwrite() / read();sendto() / recvfrom()for UDP): Copies application bytes into the TCP send buffer or reads arrived bytes from the TCP receive buffer (recv()blocks if no data has arrived yet).close(sockfd): Initiates the graceful 4-way termination handshake (sends aFINsegment) and releases the descriptor.
| System Call | Called By | Blocks Caller? | What happens on the wire (TCP)? |
|---|---|---|---|
| socket() | Client & Server | No (returns immediately) | Nothing sent on wire (allocates kernel structure). |
| bind() | Server (optional on Client) | No | Nothing sent on wire (reserves local IP:port in OS). |
| listen() | TCP Server ONLY | No | Nothing sent on wire (enables SYN/accept queues). |
| connect() | Client | YES (until SYN-ACK arrives) | Sends SYN → receives SYN-ACK → sends ACK! |
| accept() | TCP Server ONLY | YES (until a 3-way handshake finishes) | Returns NEW socket descriptor after handshake completes. |
| send() / write() | Client & Server | Usually No (unless send buffer is full) | Queues bytes for TCP segments. |
| recv() / read() | Client & Server | YES (until data arrives or peer sends FIN) | Reads in-order bytes from receive buffer. |
| close() | Client & Server | No (returns immediately; kernel sends FIN) | Triggers FIN segment (active or passive close). |
TCP vs UDP Client-Server Call Order
Compare the exact chronological order of system calls for a connection-oriented TCP server/client versus a connectionless UDP server/client:
• TCP Server:
socket() → bind() → listen() → accept() → recv() / send() → close()• TCP Client:
socket() → connect() → send() / recv() → close()UDP Call Sequences (No
listen, no accept, no handshake!):• UDP Server:
socket() → bind() → recvfrom() / sendto() → close()• UDP Client:
socket() → sendto() / recvfrom() → close()Putting it together
- A TCP server calls socket() → bind() → listen() → accept() → recv()/send() → close(), where accept() blocks and returns a new connected socket per client.
- A TCP client calls socket() → connect() → send()/recv() → close(), where connect() auto-binds an ephemeral port and sends the SYN segment.
- UDP sockets are connectionless and skip listen(), accept(), and connect(), using sendto() and recvfrom() directly.
Visual
Worked Examples
Arrange the following system calls in the correct chronological order for a standard TCP server: accept(), bind(), listen(), socket(), recv().
Show the full solution
socket() → bind() → listen() → accept() → recv(). You must create the socket first, bind it to a port, mark it passive with listen(), wait for a client with accept(), and then read data with recv().
A TCP web server calls socket(), bind(), and listen(), and then enters a loop calling accept(). If 3 clients are currently connected and actively transferring data, how many total socket descriptors exist in the server process for this service?
Show the full solution
4 socket descriptors: 1 welcome (listening) socket descriptor created by socket(), plus 3 connected socket descriptors returned by the 3 calls to accept()!
Which of the following socket calls is/are blocking by default and directly wait for network packets from the remote peer: (i) bind(), (ii) listen(), (iii) connect() on a TCP socket, (iv) accept(), (v) recv()?
Show the full solution
(iii) connect(), (iv) accept(), and (v) recv() block waiting for network events! bind() and listen() are purely local kernel operations that return immediately without sending or waiting for any packets.
GATE Traps
- Thinking
listen()blocks waiting for a client!listen()does NOT block — it simply configures the socket as passive and returns immediately. It isaccept()that blocks waiting for a client connection! - Thinking a TCP client must call
bind()! A client almost never callsbind(); when it callsconnect(), the OS kernel automatically binds an unused ephemeral source port.
Memory Hook
Server = S-B-L-A (Socket → Bind → Listen → Accept returns a NEW socket); Client = Socket → Connect (triggers SYN)!
Connect the Dots
That completes all lessons of Phase 4! Let's lock in the Socket API in L4.4 and then conquer the 15-question Phase 4 Checkpoint (CP4)!
Self-Test
- MCQ
What is the correct sequence of socket system calls made by a standard TCP server before it can read data from a client?
- socket() → listen() → bind() → accept()
- socket() → bind() → listen() → accept()
- bind() → socket() → accept() → listen()
- socket() → bind() → connect() → accept()
- MCQ
Which system call on a TCP client triggers the transmission of the initial SYN segment of the 3-way handshake?
- socket()
- bind()
- connect()
- accept()
- NAT
A concurrent TCP server creates 1 listening socket on port 443 and currently has 12 active client connections established via accept(). How many socket descriptors in total are open in the server for this port?
Write your answer before opening the key.
- MSQ
Which of the following statements about the Berkeley Socket API are TRUE?
- The listen() system call is non-blocking; it simply marks the socket as passive and allocates kernel connection queues.
- Each successful call to accept() returns a brand-new socket descriptor dedicated to that client connection.
- A UDP server does not call listen() or accept().
- A TCP client must always call bind() before calling connect().
Rule Card
- TCP Server order:
socket() → bind() → listen() → accept() → recv()/send() → close(). - TCP Client order:
socket() → connect() → send()/recv() → close()(OS auto-binds ephemeral port). - UDP Server / Client: no
listen()oraccept(); usesrecvfrom() / sendto()on a single bound socket. - Blocking calls:
connect(),accept(), andrecv()block by default;listen()does NOT block.
Concept Ledger
- Berkeley Socket API
- socket(), bind(), listen(), accept(), connect(), send()/recv(), close()
- welcome (listening) socket vs connected socket
- blocking vs non-blocking calls
Answer Vault
Try the questions first. Open when you are ready to check.
Warm-up answers
- The 4-tuple: (Client IP, Client Port, Server IP, Server Port).
- The initial SYN segment from client to server!
- No! Because UDP is connectionless, a UDP server simply calls socket() and bind(), and then directly calls recvfrom() / sendto().
Self-test answers
- B — A TCP server creates an endpoint with socket(), assigns a local port with bind(), marks it passive with listen(), and waits for a client handshake with accept().
- A: bind() must precede listen() so the kernel knows which port to listen on.
- C: socket() must be first, and listen() must precede accept().
- D: connect() is called by the client, not the server.
- C — Calling connect() on a TCP socket initiates the active open by transmitting the SYN segment and blocking until the server’s SYN-ACK arrives.
- A: socket() only allocates a local kernel data structure.
- B: bind() only reserves a local address/port.
- D: accept() is called on the server, not the client.
- 13 — There is 1 listening (welcome) socket plus 12 connected sockets (one returned by each call to accept()), totaling 1 + 12 = 13 socket descriptors.
- ABC — A, B, and C are true. D is false: if a TCP client calls connect() without calling bind(), the OS kernel automatically assigns an ephemeral port.
- D: bind() is optional for clients; the OS assigns an ephemeral source port automatically.
Flashcards
- What is the exact sequence of socket calls on a TCP server vs a TCP client?
Reveal answer
Server: socket() → bind() → listen() → accept() → recv()/send() → close(). Client: socket() → connect() → send()/recv() → close(). - Does listen() block waiting for a client connection?
Reveal answer
No! listen() returns immediately after marking the socket passive; accept() is the call that blocks waiting for a client connection. - Why does accept() return a new socket descriptor?
Reveal answer
So the server can communicate with that specific client (4-tuple) on the new descriptor while the original listening socket remains open for new clients.
Exam shortcuts
- Mnemonic for TCP Server Order — "S-B-L-A-R/S-C": Socket → Bind → Listen → Accept → Recv/Send → Close! — answering any GATE socket ordering MCQ in 3 seconds.
- Socket Descriptor Count Rule: A TCP server serving N concurrent clients has
N + 1open socket descriptors (1 listening + N accepted), whereas a UDP server serving N clients needs only1socket descriptor! — questions comparing server socket counts in TCP vs UDP.