The Socket Application Programming Interface - Linux

The socket Application Programming Interface (API) functions are described in this section. Sockets are the fundamental basis of client server programming. Generally, socket programming follows the client-server model. At the risk of over-simplifying, we will define the server as the machine that accepts connections. In contrast, a client is the machine that initiates connections. This book won’t pretend to duplicate the work of other authors on network application programming; instead, refer to [STEV98]. However, in the interest of a complete description of how the socket interface functions in Linux, the socket API functions are provided with a description of the purpose of each call. Later in this chapter, in Section you will see what happens under the covers in the Linux TCP/IP stack when each of the functions described in this section is invoked.

Before we proceed with listing the API functions, we will discuss how IP and other addresses are passed through sockets. In general, when using the socket API, network addresses are stored in a sockaddr structure defined in file linux/include/linux/in.h. This structure holds different forms of address information.

struct sockaddr_in {

Sin_port is the port number for the socket.

in_port_t sin_port;

Sin_addr is the IP address.

struct in_addr sin_addr; } ;

We use the sockaddr_in structure with the socket API because sockets are generic and intended to work with a variety of protocol families and a variety of address formats, not just IPv4 with its well-known but limited 32-bit address format. This is why the sockaddr structure can vary in length depending on the format of the address it contains.

It is important to note that the terms port and socket are not synonymous. The port, along with the IP address, identifies the destination address for a packet. However, the socket is the identifier that the application uses to access the connection to the peer machine. Linux, like most Unix operating systems, provides a complete set of functions for Internet address and port manipulation.

Like most Unix operating systems before it, Linux provides a variety of IP address conversion functions for manipulation of Internet addresses. Included are functions to convert addresses between character strings and binary numbers. An example is inet_ntoa, which converts a binary IP address to a string. The Linux functions are compatible with the traditional BSD functions for network programming that have been used for many years. These conversion functions are just about indispensable for doing any type of network application programming and are too numerous to list in this section. However, you can consult the Linux-man page inet(3) for a detailed list.

The socket API deals with addresses and ports, and it is important to note that TCP/IP, like other network protocols, always considers ports and Internet addresses passed through the socket API to be in network byte order. Network byte order is the same as big endian or Motorola byte order.

Linux, like other Unix-compatible OSs, provides a set of conversion functions to convert integers of various lengths between host byte order and network byte order. For a list of these functions, see the Linux man page byteorder(3).

One more thing should be mentioned before exploring the socket API functions. There are two types of sockets, one for individual datagrams and another for a streaming sequence of bytes. These two types of sockets reflect the difference between connectionless and connectionoriented service. The UDP protocol provides the connectionless or datagram service and is accessed through sockets of type SOCK_DGRAM. The TCP protocol is accessed through sockets of type SOCK_STREAM, which provide connection-oriented service. Most of the socket calls can be used with either socket type. However, one of the socket calls, connect, has slightly different semantics depending on the socket type, but connect is more commonly used with TCP. Two of the socket calls, accept and listen, are not used for UDP at all. In addition, recv, recvfrom, recvmsg, send, sendto, and sendmsg are usually used only with UDP. Generally, TCP servers< clients use write and read to move data to and from the sockets. Now we will look at the socket API functions, the first and most important of which is socket which opens up a new connection.

int socket(int domain, int type, int protocol);

Socket must be called first before the application can use any of the networking functi operating system for any purpose. Socket returns an identifier also known as a socket. This identifier is essentially a file descriptor and can be used in the same way as the file descriptor returned by the open system call. In other words, read and write calls can be done by specifying the socket. The first argument to the socket call, domain, specifies which protocol family will be accessed through the socket returned by this call. It should be set to one of the protocol families used in Linux (shown in Table) and for us it is generally AF_INET. In Linux generally, we use the terms protocol family and address family interchangeably.

The BSD derived socket implementations make a distinction between these two, but Linux does not. For compatibility with BSD, the protocol family is defined with names preceded by PF_, and the address families have names that begin with AF_, but the numerical values cor responding to each are identical. Type is generally set to one of three values for Linux TCP/IP. It is set to SOCK_STREAM if the caller wants reliable connection-oriented service generally provided by the TCP transport protocol. Type is specified as SOCK_DGRAM for connectionless service via the UDP transport protocol, or SOCK_RAW for direct network access to underlying protocols below the transport layer. The access to lower layer protocols is generally referred to as "raw network protocol" access. The allowed values for type are shown in Table Finally, the protocol argument to the socket call is typically set to zero when sockets are open for conventional UDP or TCP packet transmission. In some cases, though, the protocol field is used internally by the socket layer code to determine which protocol the socket accesses if the type field is insufficient. For example, to get raw protocol access to ICMP, protocol would be set to IPPROTO_ICMP and type is set to SOCK_RAW.

The next socket API call, bind, is called by applications that want to register a local address with the socket. The local address generally consists of the port number and is referred to as the name of the socket. Applications that are sending UDP packets or datagrams don’t have to call bind. If they want the peer to know where the packets came from, they should call bind.

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

Bind is usually used by application servers to associate an endpoint or port and address combination with a socket. Applications will call bind if they want the socket layer to know the port on which they will be receiving data. The port number and the local IP address are specified in myaddr in the form of the sockaddr structure. The listen API function is called by a SOCK_STREAM or TCP server to let the socket layer know that it is ready to receive connection requests on the sockets.

int listen (int s, int backlog );

Backlog specifies the length of the queue of pending connection requests while the server is waiting for the accept call to complete. Accept is called by the application when it is ready to accept a connection request. It returns a new socket for the accepted connection. The address of the peer requesting the connection is placed in the sockaddr structure pointed to by addr. Addrlen should point to a variable containing the size of struct sockaddr before calling accept. After the function call returns, addrlen points to the length of the new address in addr.

int accept (int s, struct sockaddr *addr, socklen_t *addrlen);

The socket call, connect, is primarily used by a client application to establish a connectionoriented or SOCK_STREAM type connection with a server using the TCP protocol.

int connect (int s const struct sockaddr *serv_addr, socklen_t addrlen);

Serv_addr specifies the address and port of the server with which the caller wants to make a connection, and addrlen is set to the length of struct sockaddr. When used with TCP, connect actually causes TCP to initiate the connection negotiation between peers. Connect may also be used with SOCK_DGRAM, but in this case it does not actually cause a connection; instead, it only specifies the peer address information so the send call can be used through the socket, s. The socket call, socketpair, is not used for TCP/IP so it will not be discussed here. It is used for AF_UNIX domain sockets for inter-process communication within a system. We will see later as we discuss the internal structure of the socket layer that quite a bit of the complexity of sockets is due the fact that they must support AF_UNIX based inter-process communication. The next three socket calls—send, sendto, and sendmsg—each transmit data from socket s to a peer socket. Send is used only with a socket that has been connected, either as a server or client by having previously called connect. Sendto is used with any open SOCK_DGRAM socket because it includes the arguments to and tolen, which specify the address of the destination.

Normally, these calls will block until there is sufficient buffer space to receive the packet of the specified length. The flags argument can contain any of the following values. All the socket flags are shown with their values in Table

struct msghdr {

Socket API Function Values for Flags

Socket API Function Values for FlagsSocket API Function Values for Flags

Msg_name contains the "name" of the socket. This is the destination IP address and port number for this message. Msg_namelen is the length of the address pointed to by msg_name.

void * msg_name; socklen_t msg_namelen;

Msg_iov is an array of buffers of data to be sent or received. It is often referred to as the "scatter gather array" but it is not used only for DMA operations. Msg_iovlen is the number of buffers in the array pointed to by msg_iov.

struct iovec * msg_iov; size_t msg_iovlen;

The following two fields are used for Posix 1003.1g ancillary data object information. The ancillary data consists of a sequence of pairs of cmsghdr and cmsg_data pairs. Msg_control is used to support the cmsg API function to pass control information to the underlying protocols. See the man page, cmsg(3) for more information.

which discusses details about rtnetlink and netlink address family and how these are used to pass control information to underlying protocols. Struct iovec is used in the msghdr structure described earlier. It is defined in file

Iov_base is a pointer to the buffer’s base address. In BSD implementations, the field is typed caddr_t.

The next three socket calls—recv, recvfrom, recvmsg—receive a message from a peer socket. As is the case with the socket call, send, recv is generally used with a connected socket.

Normally, these calls block until data is available of the specified length. Each call returns the length of the data read from the socket. After recvfrom returns, the parameters from and fromlen contain the sender’s address and length. Often these three calls are used with select to let the caller know when data is available. The argument flags may have one or more values from the list in Table All the socket flags are shown with their values in Table shown earlier. The two socket calls getsockopt and setsockopt are provided so the caller can access options or settings in the underlying protocols.

Level should be set to one of the values from Table each of which has the same values as the 1-byte protocol field in the IP header or the next header field of the IPv6 header. Generally, these values correspond with the 1-byte assigned numbers in the IANA database for IP protocol numbers. However, there are three exceptions: SOL_SOCKET, SOL_RAW, and SOL_IP. The value SOL_SOCKET indicates that the options settings refer to internal settings in the socket layer itself. SOL_RAW and SOL_IP indicate settings for IP internal protocols.

Values for Level Argument in Setsockopt System Call

Values for Level Argument in Setsockopt System Call

The optname argument is set to one of the values shown in Table These values are defined in file linux/include/asm-i386/socket.h. Before the socket layer allows certain option values to be set, it checks to ensure that the user process has the appropriate level of permissions. These permissions are called capabilities and are described later

Values for optname in Getsockopt and Setsockopt Calls

Values for optname in Getsockopt and Setsockopt CallsValues for optname in Getsockopt and Setsockopt CallsValues for optname in Getsockopt and Setsockopt CallsValues for optname in Getsockopt and Setsockopt Calls

All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd Protection Status

Linux Topics