sockets · advanced
Sockets: Partial I/O, Byte Order & Framing
Robust socket I/O accounts for three realities. First, send() and recv() may transfer fewer bytes than requested because kernel buffers are finite and TCP is flow-controlled, so you must loop — a send_all that keeps sending until every byte is out, and a receive loop that keeps reading until a full message is assembled; a recv() return of 0 indicates an orderly close by the peer (EOF), -1 is an error (EAGAIN/EWOULDBLOCK on a non-blocking socket simply means 'retry later'), and a single successful send() does not mean the whole buffer was transmitted. Second, multi-byte integers on the wire use network byte order (big-endian) so hosts of differing endianness interoperate: convert with htons/htonl before sending and ntohs/ntohl after receiving, send fixed-width types like uint32_t, and serialize field by field to avoid struct-padding surprises — forgetting this garbles length fields and port numbers on little-endian machines. Third, because TCP is a boundary-less byte stream you must frame messages yourself: either length-prefix framing (a fixed-size network-order length followed by exactly that many payload bytes, ideal for binary) or a delimiter such as CRLF (used by text protocols like HTTP); in both cases the receiver buffers partial data and only dispatches a message once it is fully reassembled.
send/recv can transfer fewer bytes than asked — loop (send_all / recv-until-complete); recv()==0 means the peer closed. Convert multi-byte ints with htonl/htons (wire is big-endian). TCP has no message boundaries, so frame with a length-prefix (binary) or delimiter (text).
The code
// send()/recv() can transfer FEWER bytes than asked — loop!ssize_t send_all(int fd, const char* p, size_t n) { size_t sent = 0; while (sent < n) { ssize_t k = send(fd, p + sent, n - sent, 0); if (k <= 0) return -1; // 0/-1 => closed or error sent += k; } return sent;}uint32_t len = htonl(msg_len); // host -> network byte order (big-endian)What this lesson walks through
- 01Short reads and short writes
- 02Network byte order
- 03Gotcha — TCP is a stream: you must frame
- 04Message framing over a byte stream
send() and recv() may process FEWER bytes than requested — the kernel buffers are finite and the network is flow-controlled. So you must loop: keep sending until all bytes are out (send_all), and keep receiving until you have a full message. A recv() return of 0 means the peer performed an orderly close (EOF); -1 is an error (EAGAIN on a non-blocking socket just means 'try later').
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of Sockets: Partial I/O, Byte Order & Framing and 100+ animated C++ interview lessons.