Understand the basic API calls for low-level socket programming.
The Sockets API is the standard low-level interface for network programming. While the exact code differs between platforms (e.g., Winsock on Windows, POSIX sockets on Linux/macOS), the concepts are universal. A **socket** is an endpoint of communication, represented in code as an object or handle. The typical server workflow is: 1. `socket()`: Create a new socket. 2. `bind()`: Associate the socket with a specific IP address and port on the local machine. This is how clients know where to connect. 3. `listen()`: Put the socket in a passive mode, waiting for incoming client connections. You can specify a backlog limit, which is the number of connections that can be queued. 4. `accept()`: This is a blocking call. The server waits here until a client tries to connect. When a connection is made, `accept()` returns a *new* socket that is dedicated to communicating with that specific client, while the original listening socket goes back to waiting for more connections. The client workflow is simpler: 1. `socket()`: Create a new socket. 2. `connect()`: Actively try to establish a connection to the server's IP address and port. Once the connection is established (i.e., the server has `accept`ed), both client and server can use `send()` and `recv()` (or `write()` and `read()`) on their respective sockets to exchange data.