Elementary Socket System Calls

socket

To do network I/O, the first thing a process must do is to call the socket system call, specifying the type of communication protocol desired.

#include        <sys/types.h>
#include        <sys/socket.h>

int socket(int family, int type, int protocol);
The family is one of
	AF_UNIX		-- Unix internal protocols
	AF_INET		-- Internet protocols
	AF_NS		-- Xerox NS Protocols
	AF_IMPLINK	-- IMP link layer
The AF_ prefix stands for "address family." In the first project, we are going to use AF_INET.

The socket type is one of the following:
	SOCK_STREAM	stream socket
	SOCK_DGRAM	datagram socket
	SOCK_RAW	raw socket
	SOCK_SEQPACKET	sequenced packet socket
	SOCK_RDM	reliably delivered message socket (not implemented yet)

The protocol argument to the socket system call is typically set to 0 for most user applications. The valid combinations are shown as follows.
family type protocol Actual protocol
AF_INET SOCK_DGRAM IPPROTO_UDP UDP
AF_INET SOCK_STREAM IPPROTO_TCP TCP
AF_INET SOCK_RAW IPPROTO_ICMP ICMP
AF_INET SOCK_RAW IPPROTO_RAW (raw)

bind

The bind system call assigns a name to an unnamed socket.
#include	<sys/types.h>
#include	<sys/socket.h>

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
The first argument is the socket descriptor returned from socket system call. The second argument is a pointer to a protocol-specific address and the third argument is the size of this address. There are three uses of bind.
  1. Servers register their well-known address with the system. It tells the system "this is my address and any messages received for this address are to be given to me." Both connection-oriented and connectionless servers need to do this before accepting client requests.
  2. A client can register a specific address for itself.
  3. A connectionless client needs to assure that the system assigns it some unique address, so that the other end (the server) has a valid return address to send its responses to. This corresponds to making certain an envelope has a valid return address, if we expect to get a reply from the person we sent the letter to.

connect

A client process connects a socket descriptor following the socket system call to establish a connection with a server.
#include	<sys/types.h>
#include	<sys/socket.h>

int connect(int sockfd, struct sockaddr *servaddr, int addrlen);
The sockfd is a socket descriptor that was returned by the socket system call. The second and third arguments are a pointer to a socket address, and its size, as described earlier.
For most connection-oriented protocols (TCP, for example), the connect system call results in the actual establishment of a connection between the local system and the foreign system.
The connect system call does not return until the connection is established, or an error is returned to the process.
The client does not have to bind a local address before calling connect. The connection typically causes these four elements of the association 5-tuple to be assigned: local-addr, local-process, foreign-addr, and foreign-process. In all the connection-oriented clients, we will let connect assign the local address.

listen

This system call is used by a connection-oriented server to indicate that it is willing to receive connections.
#include	<sys/types.h>
#include	<sys/socket.h>

int listen(int sockfd, int backlog);
It is usually executed after both the socket and bind system calls, and immediately before the accept system call. The backlog argument specifies how many connection requests can be queued by the system while it waits for the server to execute the accept system call. This argument is usually specified as 5, the maximum value currently allowed.

accept

After a connection-oriented server executes the listen system call described above, an actual connection from some client process is waited for by having the server execute the accept system call.
#include	<sys/types.h>
#include	<sys/socket.h>

int accept(int sockfd, struct sockaddr *peer, int *addrlen);
accept takes the first connection request on the queue and creates another socket with the same properties as sockfd. If there are no connection requests pending, this call blocks the caller until one arrives.
The peer and addrlen arguments are used to return the address of the connected peer process (the client). addrlen is called a value-result argument: the caller sets its value before the system call, and the system call stores a result in the variable. For this system call the caller sets addrlen to the size of the sockaddr structure whose address is passed as the peer argument.

send, sendto, recv and recvfrom

These system calls are similar to the standard read and write system calls, but additional arguments are required.
#include	<sys/types.h>
#include	<sys/socket.h>

int send(int sockfd, char *buff, int nbytes, int flags);
int sendto(int sockfd, char *buff, int nbytes, int flags, struct sockaddr *to, int addrlen);
int recv(int sockfd, char *buff, int nbytes, int flags);
int recvfrom(int sockfd, char *buff, int nbytes, int flags, struct sockaddr *from, int *addrlen);
The first three arguments, sockfd, buff, and nbytes, to the four system calls are similar to the first three arguments for read and write. The flags argument can be safely set to zero ignoring the details for it. The to argument for sendto specifies the protocol-specific address of where the data is to be sent. Since this address is protocol-specific, its length must be specified by addrlen. The recvfrom system call fills in the protocol-specific address of who sent the data into from. The length of this address is also returned to the caller in addrlen. Note that the final argument to sendto is an integer value, while the final argument to recvfrom is a pointer to an integer value.

close

The normal Unix close system call is also used to close a socket.
int close(int fd);
If the socket being closed is associated with a protocol that promises reliable delivery (e.g., TCP or SPP), the system must assure that any data within the kernel that still has to be transmitted or acknowledged, is sent. Normally, the system returns from the close immediately, but the kernel still tries to send any data already queued.

NOTE

The above description were originally produced by Scott Seongwook Lee, sslee@cs.ucla.edu.

Last modified January 7, 1998 by mike@cs.hmc.edu