bind()
PROTOTYPE
#include <sockets.h>
int bind(int socket, const void *addr, socklen_t addrlen);
DESCRIPTION
bind() assigns a local port number and/or IP address to a socket. It is primarily used by servers and is required before calling listen(). socket is a handle returned by socket(). addr points to a sockaddr_in or sockaddr_in6 structure containing the local address, with port number and IP address in network byte order. addrlen must be greater than or equal to the IP address size. The socket address structures are reproduced below and defined in “sockets.h”:
struct sockaddr_in
{
sa_family_t sin_family; // AF_INET
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr_in6
{
uint8_t sin6_len;
sa_family_t sin6_family; // AF_INET6
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
The sin_family/sin6_family field is AF_INET for IPv4 sockets or AF_INET6 for IPv6 sockets.
The sin_port/sin6_port field is the port number. Servers use bind() to assign the “well known” port number at which they accept connection requests (TCP) or datagrams (UDP). Clients can set this field to 0 to have bind() automatically assign an unused port number to the socket.
The sin_addr/sin6_addr field can be the wildcard value (INADDR_ANY or in6addr_any) or the IP address of an attached network interface. For UDP sockets, it can also be a multicast address or (IPv4 sockets only) either the limited broadcast address (255.255.255.255) or the broadcast address of an attached network interface.
If the wildcard IP address is used, the socket accepts connection requests (TCP) or datagrams (UDP) from any network interface. This is the best setting unless the target has multiple network interfaces and it is desired to limit the socket to IP packets from a particular interface.
The sin6_len and sin6_flowinfo fields are unused. The sin6_scope_id field is only used if it is non-zero and the sin6_addr field is an IPv6 link-local address. In that case, sin6_scope_id specifies which network interface socket packets are sent to and accepted from. It should match the ‘if_index’ value of the desired network interface.
IPv4 sockets and IPv6 sockets that have the IPV6_V6ONLY option on do not share the same port number space. They can never have a port number conflict. IPv4 sockets and IPv6 sockets that have the IPV6_V6ONLY option off (the default) do share the same port number space.
The SO_REUSEADDR and SO_REUSEPORT socket options control whether the same protocol (TCP or UDP), local IP address, and local port number can be assigned to more than one socket. The table below shows the result of attempting to bind a second socket to a local port number already in use by a socket of the same protocol type.
In this table, IP1 and IP2 represent unique IP addresses. If the socket type is TCP, they are unicast addresses. If the socket type is UDP, they are either broadcast or unicast addresses. mcIP1 and mcIP2 represent unique multicast IP addresses. The Default column indicates the behavior when neither SO_REUSEADDR nor SO_REUSEPORT are set.
For the local port number sharing that the SO_REUSEADDR option allows (the Table 3.0 cells marked “OK”), the option is only required for sockets being bound to a local port number already in-use by another socket. For local port number sharing using SO_REUSEPORT, this option must be applied to all sockets sharing the same local port number.
| socket1 | socket2 | Default | SO_REUSEADDR | SO_REUSEPORT |
| IP1 | IP2 | OK | OK | OK |
| IP1 | IP1 | error | error | OK if UDP |
| IP1 | wildcard | error | OK | OK |
| wildcard | IP1 | error | OK | OK |
| wildcard | wildcard | error | error | OK if UDP |
| mcIP1 | mcIP2 | OK | OK | OK |
| mcIP1 | mcIP1 | error | OK | OK |
Table of SO_REUSEADDR/SO_REUSEPORT Effects
If successful, bind() returns 0. Otherwise, it sets errno and returns -1.
ERROR CODES
| EADDRINUSE | The specified protocol, port number, and IP address are already in use. |
| EADDRNOTAVAIL | The specified IP address does not have a network interface. |
| EAFNOSUPPORT | The specified address family does not match the socket type. |
| EFAULT | addr is NULL or addrlen is less than the IP address size. |
| EINVAL | The socket is already bound to an address. |
| ENETDOWN | TargetTCP has not been initialized. |
| ENOTSOCK | socket is not a valid socket handle. |
EXAMPLES
struct sockaddr_in addr;
/*-------------------------------------------------------------------*/
/* Assign local address to IPv4 socket. */
/*-------------------------------------------------------------------*/
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(500);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(psock, &addr, sizeof(addr)))
error("bind() failed");
struct sockaddr_in6 addr;
/*-------------------------------------------------------------------*/
/* Assign local address to IPv6 socket. */
/*-------------------------------------------------------------------*/
bzero(&addr, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(0);
addr.sin6_addr = in6addr_any;
if (bind(sock, &addr, sizeof(addr)))
error("bind() failed");