Networking in C · intermediate · ~8 min

Common socket errors

Recognize the `errno` values you will see most often, and understand what each one means.

Lesson

When a socket call fails, it returns -1 and sets the global variable errno. The value of errno tells you why it failed. Knowing the common values lets you decide whether to retry, give up, or report the problem.

Common errno values

errno Where you see it What it means
EADDRINUSE bind The port is already taken. Use SO_REUSEADDR or pick another port.
EACCES bind You tried to use a privileged port (below 1024) without root.
ECONNREFUSED connect Nothing is listening on that address and port.
ETIMEDOUT connect The connection request (SYN) got no answer.
ECONNRESET recv / send The peer crashed or closed abruptly (it sent an RST instead of a clean FIN).
EPIPE send The peer already closed. SIGPIPE was raised (unless you used MSG_NOSIGNAL).
EAGAIN non-blocking sockets The call would block right now. Try again later.
EINTR any syscall A signal interrupted the call. Retry it, or set SA_RESTART.
ENETUNREACH connect No route to the destination exists. You will see this in --network=none sandboxes.

A quick note on the terms above:

  • SYN, FIN, RST are TCP control packets. SYN starts a connection, FIN closes it cleanly, and RST tears it down abruptly.
  • SIGPIPE is a signal the system sends when you write to a closed connection. By default it kills your program.

Pattern for robust code

Wrap every socket call in an error check:

if (rc < 0) {
    switch (errno) {
        /* handle each case */
    }
}

The key idea is that your loop must know the difference between two kinds of failure:

  • Retryable errors (EINTR, EAGAIN) — try the call again.
  • Fatal errors (everything else) — stop and report.

Code examples

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;

Common mistakes

  • Treating every -1 from a syscall as fatal. EINTR and EAGAIN are retryable — the call simply needs to run again.

Summary

  • Memorize these names: EADDRINUSE, ECONNREFUSED, ECONNRESET, EPIPE, EAGAIN, EINTR.
  • Retry on EINTR and EAGAIN.
  • Treat every other error as fatal: report it and stop.

Practice with these exercises