We are moving down the checklist of setting up a server.

  1. socket(): Install the telephone (Done).
  2. bind(): Assign a phone number so people can call you.

In technical terms, bind assigns a local protocol address to a socket. For TCP/IP, this “address” is the combination of an IP address and a Port number.

1. The Core Logic: bind()

The kernel needs to know which local IP address and which local port your application wants to use to receive data.

Function Prototype:

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

Returns:

  • Success: 0.
  • Error: -1 (sets errno).

2. Breakdown of Arguments

  1. sockfd: The socket descriptor (from socket()).
  2. myaddr: A pointer to the protocol-specific address structure (e.g., struct sockaddr_in). This contains the IP and Port you want to assign to this socket.
  3. addrlen: The size of that structure.

3. Server vs. Client Usage

This is a key distinction in the book:

  • Servers: MUST use bind. Servers need to register a “Well-Known Port” (like port 80 for Web Servers) so clients know where to send connection requests. If a server doesn’t bind a specific port, the kernel will assign a random ephemeral port, and no one will know how to reach it.
  • Clients: USUALLY DO NOT use bind. Clients typically don’t care which local port they use; they only care about reaching the server’s port. If a client skips bind, the kernel automatically assigns a local IP and an ephemeral port when the client calls connect.

4. Choosing Your Address (The “Wildcard”)

When a server binds, it has choices regarding the IP address it binds to. A server machine might have multiple network interfaces (e.g., Wi-Fi, Ethernet, localhost).

  • Specific IP: If you bind to a specific IP (e.g., 192.168.1.50), the socket will only accept connections arriving on that specific network card.
  • Wildcard IP (INADDR_ANY): This tells the kernel: “I don’t care which network interface the connection comes in on; if it reaches this machine on the specified port, send it to me.” This is the most common setting for general servers.

Summary of Combinations (Based on text):

IP Address ArgumentPort ArgumentResult
Wildcard0Kernel chooses IP and Port (Rare for servers).
WildcardNon-zeroKernel chooses IP; Process specifies Port (Standard for Servers).
Specific IP0Process specifies IP; Kernel chooses Port.
Specific IPNon-zeroProcess specifies both (Security/Multi-homing).

5. Common Errors: EADDRINUSE

The most common error you will encounter with bind is EADDRINUSE (“Address already in use”).

  • Scenario: You start your server, it crashes or you stop it (Ctrl+C), and you try to restart it immediately.
  • Result: bind returns -1 and errno is EADDRINUSE.
  • Why? The OS keeps the port “reserved” for a short time (the TIME_WAIT state) to clean up leftover packets from the previous connection.
  • The Fix: The text introduces a socket option called SO_REUSEADDR in Chapter 7 that tells the kernel to allow you to reuse the port immediately.

6. Code Example

Here is how a standard TCP server binds to the wildcard address and a specific port (e.g., 9877).

struct sockaddr_in servaddr;
 
// 1. Clear struct
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
 
// 2. Set the Address (INADDR_ANY = Wildcard / All Interfaces)
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
// 3. Set the Port (htons converts to network byte order)
servaddr.sin_port = htons(9877);
 
// 4. Call bind
if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
    // Check for EADDRINUSE here!
    perror("bind error");
    exit(1);
}