sockets · high
Sockets: The TCP Server/Client API Flow
The Berkeley sockets API follows a fixed call sequence. On the server: socket() creates the endpoint and returns a file descriptor; bind() assigns it a local IP and port; listen() turns it into a passive socket and creates the connection backlog queue; and accept() blocks until a client connects, returning a brand-new fd dedicated to that one connection while the listening fd continues to accept others — so you read and write on the per-connection fd, not the listener. The client is simpler: socket() then connect() to the server's IP:port, which performs the TCP three-way handshake; bind() is optional because the kernel auto-assigns an ephemeral source port. Names should be resolved with getaddrinfo(), the portable, IPv6-ready replacement for gethostbyname, which turns a host/port into sockaddr structures. A connected socket is simply a file descriptor, so read()/write() work alongside recv()/send() and it integrates with poll/epoll; every call can fail by returning -1 with errno set and must be checked, and each fd must be close()d or the process eventually exhausts descriptors (EMFILE). To serve many clients with one server, either fork/thread per connection or use I/O multiplexing (select/poll/epoll).
TCP server flow: socket -> bind -> listen -> accept (accept returns a NEW fd per client); client: socket -> connect (connect runs the handshake, bind optional). Sockets are file descriptors — resolve names with getaddrinfo, check every call for -1/errno, and close() to avoid fd leaks.
The code
// ---- SERVER ---- // ---- CLIENT ----fd = socket(AF_INET, SOCK_STREAM, 0); fd = socket(...);setsockopt(fd, SO_REUSEADDR, ...);bind(fd, &addr, sizeof addr); // assign IP:portlisten(fd, backlog); // mark as passivecfd = accept(fd, &peer, &len); connect(fd, &srv, len);recv(cfd, ...); send(cfd, ...); send(fd,...); recv(fd,...);close(cfd); close(fd); close(fd);What this lesson walks through
- 01Server side: socket → bind → listen
- 02Client connects → server's accept() returns
- 03Connected: read()/write() the conn fd, then close()
- 04Gotcha — accept() returns a new fd; check every return
The server takes four calls. socket() makes the endpoint (a file descriptor); bind() pins it to a local IP:port; listen() flips it PASSIVE so the kernel queues incoming connections.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of Sockets: The TCP Server/Client API Flow and 100+ animated C++ interview lessons.