Walk me from send() on one machine to recv() on another
“Process A calls `send(sock, buf, 1024)` and process B, on another host, is blocked in `recv()`. Describe every step, every copy, and every place the bytes can wait.”
What this tests
- Whether the candidate knows send() returns before delivery
- The two-kernel picture: socket buffers, transport, NIC on both sides
- Where latency and backpressure physically live
- Precision about copies and wake-ups
Answers by level
Read the beginner answer first and notice what is missing.
send() is a system call. The kernel looks up the descriptor, copies the 1024 bytes from user memory into the socket’s send buffer (sk_buffs) and returns the count — nothing has left the machine. If the send buffer is full the call blocks, or returns EAGAIN on a non-blocking socket.
TCP decides independently when to transmit: it builds segments up to the MSS, numbers them, and sends as many as min(cwnd, rwnd) allows, keeping a copy for retransmission. IP adds addresses and picks the next hop by longest-prefix match; the frame goes through the qdisc into the NIC’s TX ring and the NIC DMAs it onto the wire.
On host B the NIC DMAs the frame into an RX ring and raises an interrupt (or is polled); the kernel validates IP, finds the socket by 4-tuple, checks the sequence number, appends the payload to the receive buffer, and sends an ACK. Because B’s thread is sleeping on that socket’s wait queue it is marked runnable; when scheduled, recv() copies the bytes to user space — the second copy — and returns.
Green flags · Red flags
- Says explicitly that send() returns after the copy into the kernel
- Names both socket buffers and both NICs
- Mentions the scheduler wake-up on the receiving side
- Knows recv() can return partial data
- "send() sends the packet"
- Skips the receiving kernel entirely
- Thinks one send() equals one recv()
- Cannot say where the data is when send() returns