The traditional BSD Socket behavior is documented in the corresponding 3N man pages. In addition, the following new interfaces have been added to section 3N:
freeaddrinfo(3SOCKET)
freehostent(3SOCKET)
getaddrinfo(3SOCKET)
getipnodebyaddr(3SOCKET)
getipnodebyname(3SOCKET)
getnameinfo(3SOCKET)
inet_ntop(3SOCKET)
inet_pton(3SOCKET)
Socket Basics
This section describes the use of the basic socket interfaces.
Socket Creation
The socket(3SOCKET) call creates a socket in the specified family and of the specified type.
s = socket(family, type, protocol); |
If the protocol is unspecified (a value of 0), the system selects a protocol that supports the requested socket type. The socket handle (a file descriptor) is returned.
The family is specified by one of the constants defined in sys/socket.h. Constants named AF_suite specify the address format to use in interpreting names:
AF_APPLETALK | Apple Computer Inc. Appletalk network |
AF_INET6 | Internet family for IPv6 and IPv4 |
AF_INET | Internet family for IPv4 only |
AF_PUP | Xerox Corporation PUP internet |
AF_UNIX | UNIX file system |
Socket types are defined in sys/socket.h. These types, SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW, are supported by AF_INET6, AF_INET, and AF_UNIX. The following example creates a stream socket in the Internet family:
s = socket(AF_INET6, SOCK_STREAM, 0); |
This call results in a stream socket with the TCP protocol providing the underlying communication. Set the protocol argument to 0, the default, in most situations. You can specify a protocol other than the default, as described in "Advanced Socket Topics".
Binding Local Names
A socket is created with no name. A remote process has no way to refer to a socket until an address is bound to it. Communicating processes are connected through addresses. In the Internet family, a connection is composed of local and remote addresses and local and remote ports. Duplicate ordered sets, such as: protocol, local address, local port, foreign address, foreign port cannot exist. In most families, connections must be unique.
The bind(3SOCKET) interface enables a process to specify the local address of the socket. This interface forms the local address, local port set. connect(3SOCKET) and accept(3SOCKET) complete a socket's association by fixing the remote half of the address tuple. The bind(3SOCKET) call is used as follows:
bind (s, name, namelen); |
The socket handle is s. The bound name is a byte string that is interpreted by the supporting protocols. Internet family names contain an Internet address and port number.
This example demonstrates binding an Internet address.
#include <sys/types.h> #include <netinet/in.h> ... struct sockaddr_in6 sin6; ... s = socket(AF_INET6, SOCK_STREAM, 0); bzero (&sin6, sizeof (sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr.s6_addr = in6addr_arg; sin6.sin6_port = htons(MYPORT); bind(s, (struct sockaddr *) &sin6, sizeof sin6); |
The content of the address sin6 is described in "Address Binding", where Internet address bindings are discussed.
Connection Establishment
Connection establishment is usually asymmetric, with one process acting as the client and the other as the server. The server binds a socket to a well-known address associated with the service and blocks on its socket for a connect request. An unrelated process can then connect to the server. The client requests services from the server by initiating a connection to the server's socket. On the client side, the connect(3SOCKET) call initiates a connection. In the Internet family, this might appear as:
struct sockaddr_in6 server; ... connect(s, (struct sockaddr *)&server, sizeof server); |
If the client's socket is unbound at the time of the connect call, the system automatically selects and binds a name to the socket (see "Address Binding".) This is the usual way to bind local addresses to a socket on the client side.
To receive a client's connection, a server must perform two steps after binding its socket. The first step is to indicate how many connection requests can be queued. The second step is to accept a connection.
struct sockaddr_in6 from; ... listen(s, 5); /* Allow queue of 5 connections */ fromlen = sizeof(from); newsock = accept(s, (struct sockaddr *) &from, &fromlen); |
The socket handle s is the socket bound to the address to which the connection request is sent. The second parameter of listen(3SOCKET) specifies the maximum number of outstanding connections that might be queued. The from structure is filled with the address of the client. A NULL pointer might be passed. fromlen is the length of the structure. In the UNIX family, from is declared a struct sockaddr_un.
The accept(3SOCKET) routine normally blocks processes. accept(3SOCKET) returns a new socket descriptor that is connected to the requesting client. The value of fromlen is changed to the actual size of the address.
A server cannot indicate that it accepts connections from only specific addresses. The server can check the from address returned by accept(3SOCKET) and close a connection with an unacceptable client. A server can accept connections on more than one socket, or avoid blocking on the accept(3SOCKET) call. These techniques are presented in "Advanced Socket Topics".
Connection Errors
An error is returned if the connection is unsuccessful, but an address bound by the system remains. If the connection is successful, the socket is associated with the server and data transfer can begin.
The following table lists some of the more common errors returned when a connection attempt fails.
Table 6-1 Socket Connection Errors
Socket Errors | Error Description |
---|---|
ENOBUFS | Lack of memory available to support the call. |
EPROTONOSUPPORT | Request for an unknown protocol. |
EPROTOTYPE | Request for an unsupported type of socket. |
ETIMEDOUT | No connection established in specified time. This error happens when the destination host is down or when problems in the network cause in lost transmissions. |
ECONNREFUSED | The host refused service. This error happens when a server process is not present at the requested address. |
ENETDOWN or EHOSTDOWN | These errors are caused by status information delivered by the underlying communication interface. |
ENETUNREACH or EHOSTUNREACH | These operational errors can occur either because there is no route to the network or host, or because of status information returned by intermediate gateways or switching nodes. The status returned is not always sufficient to distinguish between a network that is down and a host that is down. |