Network Programming Cheatsheet · Units 1–2

Revision · 23CS7PCNWP · Units 1 and 2

Everything, on one page

Every number, name, state and prototype worth having in your head walking in. Built to print — the button in the bar gives you clean sheets with nothing interactive on them.

The numbers

The ones that get asked directly.

Sizes and limits

Max IPv4 datagram
65,535 (incl. header)
Max IPv6 datagram
65,575 (incl. 40-byte header)
Ethernet MTU
1,500
Min link MTU, IPv4
68
Min link MTU, IPv6
1,280
Min reassembly, IPv4
576
Min reassembly, IPv6
1,500
Typical IPv4 MSS
1,460 (1500 − 20 − 20)
Max advertised window
65,535 (16-bit field)
With window scale
65,535 × 2¹⁴ ≈ 1 GB

Structure sizes

sockaddr_in
16 bytes
sockaddr_in6
28 bytes
sockaddr
16 bytes
sockaddr_storage
128 bytes (typical)
in_addr
4 bytes (32-bit)
in6_addr
16 bytes (128-bit)
INET_ADDRSTRLEN
16
INET6_ADDRSTRLEN
46

Times

TIME_WAIT
2MSL — 1 to 4 minutes
MSL, RFC 1122
2 minutes
MSL, Berkeley
30 seconds
Max hop limit / TTL
255
connect timeout
~75 seconds
Incomplete-queue timeout
75 seconds
Data retransmit give-up
12 tries, ~9 minutes
SO_KEEPALIVE idle
2 hours
init SIGTERM → SIGKILL
5–20 seconds
Delayed ACK
up to 200 ms

Port ranges (IANA)

0 – 1023
Well-known · IANA-assigned · Unix reserved
1024 – 49151
Registered · listed, not controlled
49152 – 65535
Dynamic / private · ephemeral

FTP 21 · daytime 13 · HTTP 80 · TFTP UDP 69 · book's SERV_PORT 9877. 49152 = ¾ of 65536.

Counts to quote

TCP states
11
TCP handshake
3 packets
TCP teardown
4 packets
SCTP handshake
4 packets
SCTP shutdown
3 packets
Process → kernel fns
3
Kernel → process fns
4
Conversion functions
5
Inherited socket options
11
TCP overhead, 1 req/reply
8 segments (vs 2 for UDP)

The calls

Prototypes, in the order you use them.

Elementary TCP

int socket(int family, int type,
           int protocol);

int connect(int sockfd,
      const struct sockaddr *servaddr,
      socklen_t addrlen);

int bind(int sockfd,
      const struct sockaddr *myaddr,
      socklen_t addrlen);

int listen(int sockfd, int backlog);

int accept(int sockfd,
      struct sockaddr *cliaddr,
      socklen_t *addrlen);

int close(int sockfd);

Server: socket → bind → listen → accept. Client: socket → connect.

Names, options, processes

int getsockname(int sockfd,
      struct sockaddr *localaddr,
      socklen_t *addrlen);
int getpeername(int sockfd,
      struct sockaddr *peeraddr,
      socklen_t *addrlen);

int getsockopt(int sockfd, int level,
      int optname, void *optval,
      socklen_t *optlen);
int setsockopt(int sockfd, int level,
      int optname, const void *optval,
      socklen_t optlen);

pid_t fork(void);
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc,
              int options);

Byte order and conversion

uint16_t htons(uint16_t);  /* h→n, 16 */
uint32_t htonl(uint32_t);  /* h→n, 32 */
uint16_t ntohs(uint16_t);  /* n→h, 16 */
uint32_t ntohl(uint32_t);  /* n→h, 32 */

int   inet_aton(const char *,
                struct in_addr *);
in_addr_t inet_addr(const char *);
char *inet_ntoa(struct in_addr);

int   inet_pton(int family,
        const char *, void *);
const char *inet_ntop(int family,
        const void *, char *, size_t);

Test inet_pton with <= 0. htonl for the address, htons for the port.

Byte manipulation

JobBSDANSI
zerobzero(d,n)memset(d,0,n)
copybcopy(s,d,n)memcpy(d,s,n)
comparebcmp(a,b,n)memcmp(a,b,n)

Argument order reverses. bcmp = equal / not equal; memcmp = <, =, >.

Return values that catch people

read → 0
EOF: peer sent FIN. Not an error.
read → −1
Error. Check errno.
read short
Normal. Loop — use readn.
inet_aton
1 = OK, 0 = error
inet_pton
1 OK, 0 bad string, −1 error
inet_ntop
pointer, or NULL
fork
0 in child, PID in parent
accept
NEW descriptor
errno EINTR
Interrupted — restart the call

The diagrams

Interactive here; they print as their final complete frame.

The states, the options, the errors

11 TCP states

CLOSEDstart and end
LISTENpassive open done
SYN_SENTactive open, SYN sent
SYN_RCVDSYN+ACK sent, awaiting 3rd
ESTABLISHEDdata transfer
FIN_WAIT_1active close, FIN sent
FIN_WAIT_2our FIN ACKed, half-closed
CLOSE_WAITpassive close, awaiting our close
CLOSINGsimultaneous close only
LAST_ACKpassive close, awaiting final ACK
TIME_WAITactive closer waits 2MSL

Normal paths

Client
CLOSED → SYN_SENT → ESTABLISHED
→ FIN_WAIT_1 → FIN_WAIT_2
→ TIME_WAIT → CLOSED

Server
CLOSED → LISTEN → SYN_RCVD
→ ESTABLISHED → CLOSE_WAIT
→ LAST_ACK → CLOSED

TIME_WAIT — the two reasons

  1. Reliable full-duplex close. If the final ACK is lost the peer resends its FIN, so this end must keep state to resend the ACK — otherwise it would answer with an RST, read as an error.
  2. Let old duplicates expire. Stops an old segment reaching a new incarnation of the same socket pair.

2MSL = one MSL out, one MSL back. Only the active-close end waits.

Value-result — the 3 and the 4

Process → kernel (plain value):

bind · connect · sendto

Kernel → process (value-result):

accept · recvfrom · getsockname · getpeername

In: how big the buffer is, so the kernel does not overrun it. Out: how much it actually stored. Also getsockopt and select's middle three.

Q2(c) — the five options

OptionLevelKindType
IP_TTLIPPROTO_IPvalueint
SO_BROADCASTSOL_SOCKETflagint
TCP_MAXSEGIPPROTO_TCPvalueint
IPV6_DONTFRAGIPPROTO_IPV6flagint
SO_LINGERSOL_SOCKETvaluelinger{}

Flag = on/off, int. Value = carries a value of the stated type.

SO_LINGER — three cases

onofflingerclose does
0returns at once (default)
≠00abort: discard data, send RST, no TIME_WAIT
≠0≠0sleep until ACKed or time expires (then EWOULDBLOCK, data discarded)

11 inherited options

SO_DEBUG · SO_DONTROUTE · SO_KEEPALIVE · SO_LINGER · SO_OOBINLINE · SO_RCVBUF · SO_RCVLOWAT · SO_SNDBUF · SO_SNDLOWAT · TCP_MAXSEG · TCP_NODELAY

Set them on the listening socket — the connected socket is made by the kernel during the handshake, before accept returns.

Server host goes away

CaseSendsClient sees
crashnothingETIMEDOUT (~9 min)
crash+rebootRSTECONNRESET
shutdownFINread → 0
router says noICMPEHOSTUNREACH

FIN = goodbye. RST = denial. Silence = 9 minutes of retries.

connect errors

ETIMEDOUT
no reply · ~75 s
ECONNREFUSED
RST · hard error
EHOSTUNREACH
ICMP · soft error
ENETUNREACH
ICMP · soft error

RST is generated when: a SYN arrives for a port with no listener; TCP aborts a connection; a segment arrives for a connection that does not exist.

Signals

SIGCHLD
child died · default IGNORED → zombies
SIGPIPE
wrote to a socket that got an RST → EPIPE
SIGTERM
shutdown · catchable
SIGKILL
not catchable, not ignorable
SIGSTOP
not catchable, not ignorable
while ((pid = waitpid(-1, &stat,
                 WNOHANG)) > 0)
    ;   /* loop: signals aren't queued */

The two listen queues

Incomplete
SYN arrived · SYN_RCVD
Completed
handshake done · ESTABLISHED

SYN → incomplete → (3rd segment) → completed → accept takes the first. Timeout on incomplete: 75 s. Sum bounded by backlog. Creation is automatic — the server process is not involved.

TCP vs SCTP

TCPSCTP
open34
close43
addresses1many
streams1many
boundariesnoyes
half-closeyesno
TIME_WAITyesno
state on 1st pktallocatedcookie

SCTP: INIT → INIT-ACK(cookie) → COOKIE-ECHO → COOKIE-ACK. Close: SHUTDOWN → SHUTDOWN-ACK → SHUTDOWN-COMPLETE.

Traps

The specific things that cost marks.

Byte order

  • htonl for the 32-bit address, htons for the 16-bit port. Not the other way round.
  • "s" and "l" mean 16-bit and 32-bit, not short and long. Under LP64 a long is 64 bits.
  • ntohs before printing a port from accept.
  • On a big-endian machine these are null macros — omitting them is a bug that hides.

Structures

  • bzero the structure first — sin_zero and sin_len are never assigned by you.
  • Every socket call needs the (SA *) cast.
  • sockaddr is 16 bytes; sockaddr_in6 is 28 — which is why sockaddr_storage exists.
  • Reset len = sizeof(addr) inside the accept loop.

Streams

  • TCP has no record boundaries. One write ≠ one read.
  • A short count is not an error — loop, or use readn/writen.
  • read returning 0 is EOF, not failure.
  • fgets keeps the newline — strip it before strlen.
  • Never write a raw struct down a socket: byte order and padding differ.

Concurrency

  • Child closes listenfd; parent closes connfd.
  • close only decrements — the FIN goes when the count hits 0.
  • Catch SIGCHLD and reap in a loop with WNOHANG.
  • Then handle EINTR from accept — but never restart connect.

Deprecated / wrong answers

  • inet_addr — cannot express 255.255.255.255. Use inet_aton or inet_pton.
  • inet_ntoa — returns static memory, not re-entrant.
  • SO_LINGER with 0 to dodge TIME_WAIT — use SO_REUSEADDR. RFC 1337.
  • sprintf — use snprintf.
  • backlog is not the number of clients.

Terminology

active open
connect() — the client
passive open
listen() — the server
active close
closed first → TIME_WAIT
passive close
received FIN → CLOSE_WAIT
socket
one IP + one port
socket pair
the four-tuple
incarnation
a new connection, same four-tuple
wandering duplicate
packet lost in a routing loop
association
SCTP's word for a connection
long fat pipe
high bandwidth or long delay

The paper

2026 format — 50 marks.

Structure

PartLevelMarks
IRemember / Understand
answer all · 5 + 5
10
IIApply
2a compulsory, then 2b OR 2c
20
IIIDesign / Analyze
whole of Q3 OR whole of Q4 · 8 + 6 + 6
20

Part II is programs. Part III is all-or-nothing — you cannot mix 3a with 4b.

Where everything is