The bind() call binds a unique local name to the socket using descriptors. After calling socket(), the descriptor does not have a name associated with it. However, it does belong to a particular addressing family, as specified when socket() is called. The exact format of a name depends on the addressing family. The bind() call also allows servers to specify the network interfaces from which they want to receive UDP packets and TCP connection requests.
#include <manifest.h>
#include <bsdtypes.h>
#include <socket.h>
#include <in.h>
int bind(int s, struct sockaddr *name, int namelen)
The s parameter is a socket descriptor of any type created by calling socket().
The name parameter points to a buffer containing the name to be bound to s. The namelen parameter is the size, in bytes, of the buffer pointed to by name.
Socket descriptor created in the AF_INET domain
struct in_addr
{
u_long s_addr;
};
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
The sin_family field must be set to AF_INET.
The sin_port field identifies the port to which the application must bind. It must be specified in network byte order. If sin_port is set to 0, the caller expects the system to assign an available port. The application can call getsockname() to discover the port number assigned.
The in_addr sin_addr field is set to the internet address and must be specified in network byte order. On hosts with more than one network interface (called multihomed hosts), a caller can select the interface to which it should bind. Subsequently, only UDP packets and TCP connection requests from this interface (the one value matching the bound name) are routed to the application. If this field is set to the constant INADDR_ANY, as defined in IN.H, the caller is requesting that the socket be bound to all network interfaces on the host. Subsequently, UDP packets and TCP connections from all interfaces matching the bound name are routed to the application. This becomes important when a server offers a service to multiple networks. By leaving the address unspecified, the server can accept all UDP packets and TCP connection requests made of its port, regardless of the network interface on which the requests arrived.
The sin_zero field is not used and should be set to all zeros.
Socket descriptor created in the AF_IUCV domain
struct sockaddr_iucv
{
short siucv_family; /* addressing family */
unsigned short siucv_port; /* port number */
unsigned long siucv_addr; /* address */
unsigned char siucv_nodeid[8]; /* nodeid to connect to */
unsigned char siucv_userid[8]; /* userid to connect to */
unsigned char siucv_name[8]; /* iucvname for connect */
};
The following examples show the bind() call. The internet address and port must be in network byte order. To put the port into network byte order, the htons() utility routine is called to convert a short integer from host byte order to network byte order. The address field is set using another utility routine, inet_addr(), which takes a character string representing the dotted decimal address of an interface and returns the binary internet address representation in network byte order. Finally, it is a good idea to clear the structure before using it to ensure that the name requested does not set any reserved fields. See connect() for examples how a client might connect to servers.
int rc;
int s;
struct sockaddr_in myname;
struct sockaddr_iucv mymvsname;
int bind(int s, struct sockaddr *name, int namelen);
/* Bind to a specific interface in the internet domain */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr = inet_addr(“129.5.24.1”); /* specific interface */
myname.sin_port = htons(1024);
⋮
rc = bind(s, (struct sockaddr *) &myname, sizeof(myname));
/* Bind to all network interfaces in the internet domain */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr.s_addr = INADDR_ANY; /* specific interface */
myname.sin_port = htons(1024);
⋮
rc = bind(s, (struct sockaddr *) &myname, sizeof(myname));
/* Bind to a specific interface in the internet domain.
Let the system choose a port */
/* make sure the sin_zero field is cleared */
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_addr = inet_addr(“129.5.24.1”); /* specific interface */
myname.sin_port = 0;
⋮
rc = bind(s, (struct sockaddr *) &myname, sizeof(myname));
/* Bind to a name in the IUCV domain */
/* make sure the siucv_addr, siucv_port fields are zeroed and the
siucv_nodeid fields is set to blanks */
memset(&mymvsname, 0, sizeof(mymvsname));
strncpy(mymvsname.siucv_nodeid, “ ”, 8);
strncpy(mymvsname.siucv_userid, “ ”, 8);
strncpy(mymvsname.siucv_name, “ ”, 8);
mymvsname.siucv_family = AF_IUCV;
strncpy(mymvsname.siucv_userid, “MVSUSER1”, 8);
strncpy(mymvsname.siucv_name, “APPL”, 4);
⋮
rc = bind(s, (struct sockaddr *) &myname, sizeof(myname));
The binding of a stream socket is not complete until a successful call to bind(), listen(), or connect() is made. Applications using stream sockets should check the return values of bind(), listen(), and connect() before using any function that requires a bound stream socket.
gethostbyname(), getsockname(), htons(), inet_addr(), listen(), socket()