the listening socket versus the connected socket
A receptionist's desk and the meeting rooms behind it do two different jobs. The desk's only task is to greet arrivals and hand each one off to a room; the actual conversations happen in the rooms. A TCP server has the same two roles played by two kinds of socket: the listening socket is the front desk that only accepts new arrivals, and each connected socket is a private room where one client is actually served.
Concretely: the socket you create, bind(), and listen() on becomes a listening socket. Its job is narrow - it never carries your application's data. You cannot send() or recv() on it; you only call accept() on it. Each time accept() succeeds it returns a different, brand-new socket, the connected socket, bound to exactly one client. That connected socket is the one you send() and recv() on. A server typically has one listening socket alive for its whole run, and a fresh connected socket for each client, opened by accept() and closed when that client is done.
Why it matters: this is the single distinction beginners most often miss, and getting it wrong produces baffling bugs - trying to recv() on the listening socket, or reusing one client's socket for another. Keep the picture clear: one front door that only does accept(), and many private rooms that each do the talking. A connected socket is also uniquely identified by the four-tuple (local IP, local port, remote IP, remote port), which is how the OS keeps two clients on the same port from getting mixed up.
int listener = socket(...); bind(listener, ...); listen(listener, 128); int client = accept(listener, ...); Here listener stays put accepting more clients; client is the connected socket you actually recv()/send() on. They are two different file descriptors with two different jobs.
Listening socket = front door (accept only); connected socket = the room where talking happens.
send()/recv() on a listening socket is an error - it has no peer. And accept() returning a new descriptor means a busy server holds many descriptors at once, so closing each finished client socket matters.