16 Network IPC Sockets
16 Network IPC Sockets
Introduction
• Socket Programming is a method to connect two nodes over a network to
establish a means of communication between those two nodes.
• A node represents a computer or a physical device with an internet
connection. A socket is the endpoint used for connecting to a node.
• The signals required to implement the connection between two nodes are
sent and received using the sockets on each node respectively.
• A socket is an abstraction of a communication endpoint. Just as they would
use file descriptors to access files, applications use socket descriptors to
access sockets.
• Socket descriptors are implemented as file descriptors in the UNIX System.
State Diagram for Server and Client Model
• The nodes are divided into two types, server node and client node.
• The client node sends the connection signal and the server node receives the
connection signal sent by the client node.
• The connection between a server and client node is established using the
socket over the transport layer of the internet.
• After a connection has been established, the client and server nodes can share
information between them using the read and write commands.
• After sharing of information is done, the nodes terminate the connection.
Stages for Server
Socket Creation
• The first stage deals with the creation of a socket, which is the basic
component for sending or receiving signals between nodes.
• The <sys/socket.h> header has the necessary functions to create a socket
in C.
• A socket can be created by the socket() function with syntax,
• The domain represents the address family over which the
communication will be performed. The domain is pre-fixed values
present in the <sys/socket.h> header. Some domains are,
• The type represents the type of communication used in the socket, which
further determines the communication characteristics.
• Some mostly used types of communication are,
• The protocol argument is usually zero, to select the default protocol for the
given domain and socket type.
• A datagram is a self-contained message. Sending a datagram is
analogous to mailing someone a letter.
• You can mail many letters, but you can’t guarantee the order of delivery, and
some might get lost along the way.
• Each letter contains the address of the recipient, making the letter
independent from all the others. Each letter can even go to different
recipients.
• In contrast, using a connection-oriented protocol for communicating
with a peer is like making a phone call.
• First, you need to establish a connection by placing a phone call, but after the
connection is in place, you can communicate bidirectionally with each other.
• The connection is a peer-to-peer communication channel over which you
talk.
shutdown()
• Communication on a socket is bidirectional. We can disable I/O on a socket
with the shutdown function.
• The address associated with a client’s socket is of little interest, and we can
let the system choose a default address for us.
• For a server, however, we need to associate a well-known address with the
server’s socket on which client requests will arrive.
• The sockfd is the value of the file descriptor returned by the socket function.
• The addr is a structure of type sockaddr. We usually use a structure of type
sockaddr_in to represent this information, because information such as
port and address can only be stored in this structure. The sockaddr_in is
cast to the sockaddr data type when calling the bind function.
• The len represents the size of the address passed as the second parameter.
Connection Establishment
• If we’re dealing with a connection-oriented network service (SOCK_STREAM
or SOCK_SEQPACKET), then before we can exchange data, we need to create
a connection between the socket of the process requesting the service (the
client) and the process providing the service (the server).
• We use the connect function to create a connection.
• The address we specify with connect is the address of the server with
which we wish to communicate.
• If sockfd is not bound to an address, connect will bind a default address
for the caller.
• This function shows
what is known as an
exponential backoff
algorithm.
• If the call to connect
fails, the process goes to
sleep for a short time and
then tries again,
increasing the delay each
time through the loop, up
to a maximum delay of
about 2 minutes.
listen()
A server announces that it is willing to accept connect requests by calling the
listen function.
• The backlog argument provides a hint to the system regarding the number of
outstanding connect requests that it should enqueue on behalf of the process.
• The actual value is determined by the system, but the upper limit is specified as
SOMAXCONN in <sys/socket.h>.
• Once the queue is full, the system will reject additional connect requests, so the
backlog value must be chosen based on the expected load of the server and the
amount of processing it must do to accept a connect request and start the
service.
accept()
Once a server has called listen, the socket used can receive connect requests.
We use the accept function to retrieve a connect request and convert it into a
connection.
• The file descriptor returned by accept is a socket descriptor that is
connected to the client that called connect.
• This new socket descriptor has the same socket type and address family as
the original socket (sockfd).
• The original socket passed to accept is not associated with the
connection, but instead remains available to receive additional connect
requests.
• If we don’t care about the client’s identity, we can set the addr and len
parameters to NULL.
• Otherwise, before calling accept, we need to set the addr parameter to a buffer
large enough to hold the address and set the integer pointed to by len to the size
of the buffer in bytes.
• On return, accept will fill in the client’s address in the buffer and update the
integer pointed to by len to reflect the size of the address.
Data Transfer
• Since a socket endpoint is represented as a file descriptor, we can use read
and write to communicate with a socket, as long as it is connected.
• Using read and write with socket descriptors is significant, because it
means that we can pass socket descriptors to functions that were originally
designed to work with local files.
• We can also arrange to pass the socket descriptors to child processes that
execute programs that know nothing about sockets.
• Although we can exchange data using read and write, that is about all we
can do with these two functions.
• If we want to specify options, receive packets from multiple clients, or send
out-of-band data, we need to use one of the six socket functions designed for
data transfer.
• Three functions are available for sending data, and three are available for
receiving data.
send()
• The simplest one is send. It is similar to write, but allows us to specify
flags to change how the data we want to transmit is treated.
• The sendto function is similar to send. The difference is that sendto allows
us to specify a destination address to be used with connectionless sockets.
• With a connection-oriented socket, the destination address is ignored, as the
destination is implied by the connection.
• With a connectionless socket, we can’t use send unless the destination address
is first set by calling connect, so sendto gives us an alternate way to send a
message.
sendmsg()
• We can call sendmsg with a msghdr structure to specify multiple buffers
from which to transmit data.
recv()