Networking in C · intermediate · ~10 min
Transition a socket from bound to listening, then accept incoming connections.
listen(fd, backlog) marks fd as accepting connections; backlog is the kernel's queue depth for half-finished SYN/ACK handshakes (32 is fine for labs).
accept(fd, &peer, &peer_len) blocks until a client connects, then returns a new fd for that one connection. The original fd keeps listening for the next client.
Server loop skeleton:
listen(srv_fd, 32);
for (;;) {
struct sockaddr_in peer; socklen_t plen = sizeof peer;
int client_fd = accept(srv_fd, (struct sockaddr *)&peer, &plen);
if (client_fd < 0) { perror("accept"); continue; }
/* talk to client_fd, then close it */
close(client_fd);
}
int srv = socket(AF_INET, SOCK_STREAM, 0);
/* … setsockopt + bind on 127.0.0.1:8080 … */
listen(srv, 32);
struct sockaddr_in peer; socklen_t plen = sizeof peer;
int client = accept(srv, (struct sockaddr *)&peer, &plen);
write(client, "hi\n", 3);
close(client);
close(srv);
client_fd after each connection. fd leak.srv_fd and client_fd as the same thing. They're separate sockets.listen() puts a bound socket into listening mode. accept() returns a fresh fd for each incoming connection. Close the per-client fd when done.