🌐Go deeper — read the bookTCP is a stream: framing & byte order— runnable code & full walkthrough →

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.

🔑 Key line

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

  1. 01Short reads and short writes
  2. 02Network byte order
  3. 03Gotcha — TCP is a stream: you must frame
  4. 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.

← Previous
Sockets: Blocking, Non-blocking & epoll
Next →
Sockets: Key Options - SO_REUSEADDR, TCP_NODELAY, Keepalive