Networking in C · intermediate · ~8 min
Recognise the errno values you'll see most often and what each means.
| errno | meaning |
|---|---|
| EADDRINUSE | bind: port already taken — use SO_REUSEADDR or pick another port |
| EACCES | bind: trying to use a privileged port (< 1024) without root |
| ECONNREFUSED | connect: nothing is listening on that (addr, port) |
| ETIMEDOUT | connect: SYN unanswered |
| ECONNRESET | recv/send: the peer crashed or closed abruptly (RST instead of FIN) |
| EPIPE | send: peer already closed; SIGPIPE was raised (or you used MSG_NOSIGNAL) |
| EAGAIN | non-blocking: would block now, try again later |
| EINTR | a signal interrupted the syscall — retry, or use SA_RESTART |
| ENETUNREACH | route to the destination doesn't exist (you'll see this in --network=none sandboxes) |
Pattern for robust code: every socket call goes through if (rc < 0) { switch(errno) { … } }, and the loop knows the difference between "retry (EINTR/EAGAIN)" and "give up".
ssize_t n;
do { n = recv(fd, buf, cap, 0); } while (n < 0 && errno == EINTR);
if (n < 0) perror("recv");
else if (n == 0) printf("peer closed\n");
else buf[n] = 0;
-1 from a syscall as fatal. EINTR and EAGAIN are retryable.Memorise EADDRINUSE, ECONNREFUSED, ECONNRESET, EPIPE, EAGAIN, EINTR. Retry EINTR/EAGAIN; surface everything else.