The master loop of a concurrent connection-oriented server
The master loop of a concurrent connection-oriented server
Answer
for (;;) { int c = accept(s, NULL, NULL); if (c < 0) { if (errno == EINTR) continue; break; } if (fork() == 0) { close(s); serve(c); close(c); _exit(0); } close(c); /* the master keeps only the passive socket */ }
Both closes matter. The slave closes the *listening* socket it does not need; the master closes its copy of the *accepted* socket, without which the connection never fully tears down when the slave exits. `_exit()` rather than `exit()` in the child avoids flushing the parent's buffered output twice.
S&K 3e ch20 §20.7–20.9; child reaping and SO_REUSEADDR from Stevens & Rago, APUE 3e ch16 — both absent from the textbook