Skip to content

Sockets

Sockets are file descriptors that serve as the communication end-points for processes running on a operating system like Linux. A socket connection is a bidirectional communication interface that allows two processes to exchange information within a network.

Sockets are the interface to use the TCP protocol. Sockets allow applciations to send and receive data from a TCP connection just like reading and writing to a file using a file descriptor. Hence they are used to implement client and server applications. The server process creates a socket and listens on it for clients' requests.

socket.png

The main two types of sockets in networking:

  • SOCK_STREAM: Stream sockets ensure that data is delivered in the order it was sent and without errors. For example web browsing (HTTP), email (STMP), etc use this socket type (TCP).
  • SOCK_DGRAM: Datagram sockets send packets of data, called datagrams, without establishing a connection or ensuring delivery. For example video streaming, online gaming etc. use this socket type (UDP).

Each network socket is associated with an IP address and a port number, identifying both the host and a specific application or service.

Flow of events

Sockets used in a client-server model has a typical flow of events. The following figure shows the typical flow of events (and the sequence of issued APIs) for a connection-oriented socket session. An explanation of each event follows the figure.

We will be using the following functions to setup TCP connections:

socket-flow.png

int socket() Create an endpoint for communication
Argument NameArgument TypeDescription
domainintSpecifies the communication domain (e.g., AF_INET for IPv4).
typeintSpecifies the communication semantics (e.g., SOCK_STREAM for TCP).
protocolintSpecifies a particular protocol to be used with the socket. (default 0)
int bind() Binds a socket to a local address
Argument NameArgument TypeDescription
sockfdintFile descriptor of the socket to bind.
addrconst struct sockaddr *Pointer to a sockaddr structure that contains the address to bind to.
addrlenint / socklen_tSize of the address structure.
int listen() Listen for connections on a socket
Argument NameArgument TypeDescription
sockfdintFile descriptor of the socket(server) to listen on.
backlogintmaximum length of the queue maintaining pending connections
int connect() Initiates a connection on a socket.
Argument NameArgument TypeDescription
sockfdintFile descriptor of the socket(client).
addrconst struct sockaddr *Pointer to a sockaddr structure that contains the address to connect to (server address).
addrlenint / socklen_tSize of the address structure.
int accept() Accepts an incoming connection on a listening socket.
Argument NameArgument TypeDescription
sockfdintFile descriptor of the listening socket.
addrconst struct sockaddr *Pointer to a sockaddr structure to receive the address of the connecting entity.
addrlenint / socklen_tSize of the address structure.
int send() Send a message on a socket
Argument NameArgument TypeDescription
sockfdintFile descriptor of the connected socket.
bufconst void *Pointer to he buffer containing the data to be sent.
lenintLength of the data to be sent.
flagsintBitwise OR of flags controlling the operation(Default 0).
int recv() Recieves a message from a socket
Argument NameArgument TypeDescription
sockfdintFile descriptor of the connected socket.
bufconst void *Pointer to the buffer to receive the data.
lenintLength of the buffer.
flagsintBitwise OR of flags controlling the operation(Default 0).
int close() Closes a socket
Argument NameArgument TypeDescription
sockfdintFile descriptor of the socket to close.
  1. Socket creation: The process begins with the creation of a socket using the socket() system call. This call initializes a communication endpoint and returns a file descriptor.
  2. Binding (optional): In server applications, the socket may be bound to a specific address and port using the bind() system call. This step is necessary for servers to listen for incoming connections on a specific network interface and port. (Bind is optional for client sockets as the operating system assigns a local address and port automatically)
  3. Listening (Server Only): Servers then enter a listening state using the listen() system call, indicating their readiness to accept incoming connections from clients.
  4. Connection Establishment (Client): Clients initiate a connection to the server by using the connect() system call, specifying the server's address and port. This call establishes a connection to the server, allowing for data exchange.
  5. Accepting Connections (Server): Upon receiving a connection request from a client, the server accepts the connection using the accept() system call. This call creates a new socket specifically for communication with the client.
  6. Data Exchange: Once the connection is established, both the client and server can send and receive data using the send() and recv() system calls, respectively. Data sent by one party is received by the other, allowing for bidirectional communication.
  7. Connection Termination: When communication is complete, either party can initiate the termination of the connection using the close() system call. This releases the allocated resources associated with the socket and terminates the communication channel.