Linux provides a flexible platform for communication between a wide range of applications and devices. Its robust networking component makes Linux a popular solution for running web servers and developing distributed systems and applications.
The Linux networking stack includes many network interfaces, protocols, and other components. Linux sockets are an important network data-transfer mechanism used to build networked applications, implement protocols and provide network services.
This article will focus on what Linux sockets are, the types of sockets, and how they work.
What are Linux Sockets?
Sockets are Linux file descriptors that serve as the communication end-points for processes running on that device. Each Linux socket consists of the device's IP address and a selected port number.
A socket connection is a bidirectional communication pipe that allows two processes to exchange information within a network.
What are Linux Sockets Used for
The typical sockets use case is the client-server network interaction model. In this model, the server process socket listens and waits for clients' requests. The clients exchange information with the server using TCP/IP, UDP/IP network protocols, and application-level protocols such as IMAP, POP3, SMTP, or FTP.
Although sockets primarily connect processes on a computer network, they also enable communication between processes on the same device. The same-machine connections use the IPC (Inter-process communication) sockets, also known as Unix domain sockets.
Types of Linux Sockets
There are four main types of Linux sockets.
- Stream-oriented sockets provide a reliable, connection-based communication channel.
- Datagram-oriented sockets offer a connectionless UDP-based channel.
- Raw sockets allow direct access to the underlying networking protocols.
- Sequenced packet sockets guarantee that the sent packets will arrive in the original order.
The sections below provide details on each socket type.
Stream-oriented sockets are mainly used in TCP/IP communication. Since TCP is a connection-oriented protocol, the stream sockets establish a persistent connection between two communicating processes.
The data packets sent over stream sockets arrive reliably and in the correct order, making this socket type suitable for web and email servers.
You can list the currently listening TCP sockets on Linux with the ss command:
Datagram-oriented sockets support the connectionless UDP (User Datagram Protocol). Unlike stream sockets, datagram sockets do not establish a permanent connection between two interacting processes. Instead, each packet is an independent datagram, a self-contained message whose arrival or integrity is not guaranteed.
Applications usually employ datagram-oriented UDP sockets when they require low overhead or real-time communication. For example, online gaming and VoIP use UDP because they prioritize the speed of information exchange over the integrity of the information.
ss command shows the active datagram-oriented UDP sockets on a Linux system:
Note: Bare Metal Cloud servers allow you to deploy server instances with cloud agility and connection stability, while avoiding the hypervisor overhead.
Raw sockets allow processes to access the underlying communication protocols directly. This property enables processes to avoid transport-layer formatting associated with a protocol and exchange the data at the lowest level.
Network applications that need a high level of control over communication, such as ping and traceroute, require raw sockets to function correctly. However, since raw sockets provide easy access to the link layer, their extensive use can be a security concern.
Sequenced sockets allow processes to manage incoming packets at the network layer before the packets move to the transport layer. They offer a middle-ground solution between stream and datagram-oriented sockets.
- Like stream-oriented sockets, sequenced sockets are connection-oriented.
- On the other hand, they offer datagram-like delineated packet boundaries.
How Sockets Work in Linux
Each Linux socket uses a specific domain and type. The domain determines the protocol family the socket will use, such as IPv4 or IPv6. The socket type specifies whether the socket will support reliable two-way communication (e.g., TCP) or one-way communication with best-effort delivery (e.g., UDP).
Sockets perform all the communication functions through the socket API. Using API calls, users can:
- Establish and manage connections with other systems.
- Obtain information about relevant network resources.
- Transfer data to and from the machine.
- Perform system functions.
- Stop the socket connections.
For example, to use a stream-oriented TCP socket in Linux, a user needs to start by specifying the type with the
socket() system call. The next API calls differ depending on the system's role in the network.
On the server side:
bind()- Binds a socket to a network address and port.
listen()- Tells the server to wait for incoming connections to the specified network location.
accept()- Receives the client connections.
write()- Communicate with the remote endpoint once the server establishes the communication and creates a new socket for the client.
On the client side:
connect()- Connects with the server process. Takes the address of the remote server socket as an argument.
recv()- Send and receive data, respectively.
close()- Ends the connection between the client and the server.
Datagram communication, on the other hand, does not require establishing a connection. Therefore, the server and the clients use the same system calls to exchange information between the sockets.
socket() call initializes the socket. However, since there is no need to establish a permanent connection, the datagram socket does not utilize the
accept() calls like the stream-oriented type. Instead, the
recv() calls conduct packet exchange directly.
After reading this article, you should understand the concept of a Linux socket. The article explained how Linux sockets work and discussed the most common types.