What Is a Linux Socket? A Clear Explanation for System Administrators

By LinuxCert.Guru Team·

Introduction

A socket is an endpoint for communication. When two processes need to exchange data, whether they are on the same machine or on opposite sides of the internet, they do it through sockets. One process opens a socket, another process connects to it, and data flows between them. If that sounds abstract, here is a concrete example: when your browser connects to a web server, both sides use sockets. The web server has a socket listening on port 443. Your browser opens its own socket and connects to the server's socket. From that point on, every request and response travels through that socket connection.

Understanding sockets is not an advanced topic reserved for kernel developers. It is a practical skill that every Linux administrator needs for troubleshooting network problems, understanding why services fail, and diagnosing what a process is actually doing on a system.

Sockets Are a Kernel Abstraction

In Linux, sockets are implemented in the kernel. When a program calls the socket() system call, the kernel creates a socket and gives the program a file descriptor to reference it. From the program's perspective, reading from and writing to a socket looks almost identical to reading from and writing to a file. This is intentional: Linux treats everything as a file, and sockets are no exception.

This design has a practical consequence: the same tools you use to inspect files work on sockets. lsof (list open files) shows sockets because sockets are files. File descriptors, which identify open files in a process, also identify open sockets.

The Types of Linux Sockets

Linux supports several types of sockets, and the type matters because it determines what kind of communication the socket is used for.

Socket Type Protocol What It Does Common Use
TCP socket TCP over IPv4 or IPv6 Reliable, ordered, connection-oriented. Data arrives complete and in order or the connection fails. Web servers (HTTP/HTTPS), SSH, databases, email
UDP socket UDP over IPv4 or IPv6 Connectionless, no delivery guarantee. Fast but packets can be lost or arrive out of order. DNS, NTP, streaming media, game networking
Unix domain socket Local IPC only Communication between processes on the same machine. Appears as a file in the filesystem. Nginx to PHP-FPM, PostgreSQL local connections, systemd
Raw socket Direct IP layer access Bypasses TCP/UDP, allows constructing packets at the IP level. Requires root privilege. ping (ICMP), network diagnostic tools, packet capture

Network Sockets: How They Work

A network socket is identified by five pieces of information together called a 5-tuple:

  • Protocol (TCP or UDP)
  • Local IP address
  • Local port number
  • Remote IP address
  • Remote port number

For a socket that is listening but not yet connected (like a web server waiting for connections), the remote address and port are not yet defined. For an established connection, all five values are known and together uniquely identify that specific connection on the system.

The connection lifecycle for a TCP server:

  1. The server creates a socket and binds it to an IP address and port (0.0.0.0:443 means listen on all interfaces)
  2. The server calls listen() to accept incoming connections
  3. A client connects, completing the TCP three-way handshake
  4. The kernel accepts the connection and creates a new socket specifically for that client. The original listening socket continues waiting for more connections.
  5. Data flows through the client-specific socket
  6. Either side closes the connection, the kernel tears down the socket

This is why a busy web server can have thousands of simultaneous connections all on port 443. Each connection is a separate socket with a different remote address and port, even though the local side is always port 443.

Unix Domain Sockets: The Other Kind

Unix domain sockets are used for communication between processes on the same machine. Unlike network sockets, they do not use IP addresses or port numbers. Instead, they are identified by a filesystem path, and they appear as a special file type in the directory listing.

# Find Unix domain socket files on a system
find /var/run /run /tmp -type s 2>/dev/null

# Common examples you will see:
# /run/postgresql/.s.PGSQL.5432      - PostgreSQL local connection socket
# /run/php-fpm/www.sock              - PHP-FPM socket for Nginx
# /run/systemd/private/journal.socket - systemd journal
# /var/run/docker.sock               - Docker daemon socket
# /run/dbus/system_bus_socket        - D-Bus system bus

# In a directory listing, socket files show 's' as the file type
ls -la /run/ | grep ^s

Unix domain sockets are faster than loopback network sockets (127.0.0.1) for local communication because they skip the entire network stack. This is why PostgreSQL uses a Unix socket for local connections by default, and why Nginx communicates with PHP-FPM through a socket file rather than a TCP connection when both are on the same server.

Viewing Sockets with ss

ss (socket statistics) is the modern replacement for netstat. It is faster, more detailed, and actively maintained. For any socket inspection task, use ss first.

# Show all listening TCP sockets with port numbers and the process using them
ss -tlnp

# Options breakdown:
# -t  TCP sockets only
# -l  listening sockets only
# -n  show port numbers, not service names
# -p  show the process using each socket

# Sample output:
# State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
# LISTEN  0       128     0.0.0.0:22           0.0.0.0:*         users:(("sshd",pid=1234,fd=3))
# LISTEN  0       511     0.0.0.0:80           0.0.0.0:*         users:(("nginx",pid=5678,fd=6))
# LISTEN  0       511     0.0.0.0:443          0.0.0.0:*         users:(("nginx",pid=5678,fd=7))
# Show all established TCP connections
ss -tn state established

# Show all UDP sockets
ss -ulnp

# Show Unix domain sockets
ss -xlnp

# Show everything: TCP, UDP, and Unix domain sockets, all states
ss -tulnp

# Show sockets for a specific port
ss -tlnp sport = :443

# Show sockets belonging to a specific process
ss -tlnp | grep nginx

# Show connection counts by state (useful for diagnosing load or attacks)
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

Socket States Explained

TCP sockets go through a defined sequence of states during their lifecycle. Understanding these states is essential for diagnosing connection problems.

State What It Means Normal?
LISTEN Server socket waiting for incoming connections Yes, expected for any service
ESTABLISHED Active connection, data can flow in both directions Yes, this is a live connection
TIME_WAIT Connection closed, waiting to ensure the remote side received the closure. Lasts 2 x MSL (typically 60 seconds). Normal. Becomes a problem when thousands accumulate, exhausting port ranges.
CLOSE_WAIT Remote end closed the connection, local application has not yet closed its side Should be transient. A large number of CLOSE_WAIT sockets usually means a bug in the application not closing connections properly.
SYN_SENT Client sent a SYN packet, waiting for the server's SYN-ACK Transient. Persistent SYN_SENT means the server is not reachable.
SYN_RECV Server received a SYN, sent SYN-ACK, waiting for client's ACK Should be transient. Large numbers indicate a SYN flood attack.
FIN_WAIT1 / FIN_WAIT2 Connection being actively closed, waiting for FIN from the remote side Transient. Should resolve quickly.

Common Troubleshooting Scenarios

Scenario 1: Service Not Accessible from Outside

# Check if the service is listening at all
ss -tlnp | grep :80

# If you see 127.0.0.1:80, the service is listening on loopback only
# (accessible locally but not from other machines)
# LISTEN 0 511 127.0.0.1:80 0.0.0.0:*  ← only local access

# If you see 0.0.0.0:80, the service is listening on all interfaces
# LISTEN 0 511 0.0.0.0:80  0.0.0.0:*  ← accessible from anywhere

# Fix: change the service's bind address in its configuration
# For nginx: listen 0.0.0.0:80; instead of listen 127.0.0.1:80;
# Then reload the service

Scenario 2: Port Already in Use

# When a service fails to start with "address already in use"
# Find what is using the port
ss -tlnp sport = :8080

# Or with lsof
lsof -i :8080

# Get the PID and check what process it is
ps aux | grep PID_NUMBER

# Decide whether to stop the conflicting process or change the port

Scenario 3: Too Many TIME_WAIT Sockets

# Count sockets by state
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# If TIME_WAIT count is very high on a busy server:
# Enable TCP socket reuse (allows reusing TIME_WAIT sockets for new connections)
sysctl net.ipv4.tcp_tw_reuse

# Set it temporarily
sysctl -w net.ipv4.tcp_tw_reuse=1

# Set it persistently (add to /etc/sysctl.conf)
echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.conf
sysctl -p

Scenario 4: Finding What Is Listening on a Port

# Identify the process listening on port 3306 (MySQL default)
ss -tlnp sport = :3306

# Sample output shows the process name and PID:
# LISTEN 0 151 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=2345,fd=20))

# If you do not have the -p output (requires root), use lsof as an alternative
sudo lsof -i TCP:3306 -s TCP:LISTEN

Unix Domain Sockets in Practice

Unix domain sockets appear frequently in production Linux environments. Knowing how to inspect them is a practical administration skill.

# List all Unix domain sockets and the processes using them
ss -xlnp

# Sample output:
# Netid State  Recv-Q Send-Q  Local Address:Port  Peer Address:Port  Process
# u_str LISTEN 0      128     /run/php-fpm/www.sock 0              users:(("php-fpm",pid=3456))
# u_str LISTEN 0      128     /var/run/docker.sock  0              users:(("dockerd",pid=7890))

# Check if a Unix socket file exists and has the right permissions
ls -la /run/php-fpm/www.sock

# The Nginx user must have read and write permission to the PHP-FPM socket
# If Nginx returns 502 Bad Gateway, check socket permissions first
stat /run/php-fpm/www.sock

Sockets vs Ports: Clearing Up the Confusion

These two terms are often used interchangeably but they mean different things:

  • A port is a number (0 to 65535) that identifies a specific service or communication endpoint on a machine. Port 80 is HTTP, port 443 is HTTPS, port 22 is SSH. A port is just a number, not a connection.
    • Ports below 1024 require root privilege to bind to on Linux
  • A socket is an active endpoint that uses a port (among other things) to identify itself. A socket has state: it is listening, or it is connected, or it is closed. Multiple sockets can use the same port number (many clients connected to port 443 of the same server), distinguished by their different remote addresses.

The practical distinction: when you check whether a service is running, you check whether there is a socket listening on the expected port. The port existing in configuration means nothing. The socket actually listening is the evidence the service is working.

The /proc Interface for Socket Information

The kernel exposes socket information through the /proc filesystem. Tools like ss and netstat read from here.

# TCP socket table (hexadecimal addresses and ports)
cat /proc/net/tcp

# UDP socket table
cat /proc/net/udp

# Unix domain sockets
cat /proc/net/unix

# These files are what ss and netstat read from
# ss is faster because it uses the netlink kernel interface directly
# rather than parsing text from /proc/net/

Quick Reference: Socket Inspection Commands

Task Command
Show all listening TCP ports with process info ss -tlnp
Show all listening UDP ports ss -ulnp
Show all established TCP connections ss -tn state established
Show Unix domain sockets ss -xlnp
Show everything (TCP, UDP, Unix) ss -tulnp
Find what is using a specific port ss -tlnp sport = :PORT
Count connections by state ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c
Find open files including sockets for a process lsof -p PID
Find Unix domain socket files find /var/run /run -type s
Check socket file permissions ls -la /path/to/socket.sock

Conclusion

A socket is an endpoint for communication between processes, either on the same machine or across a network. Linux implements them as file descriptors, which is why the same tools that inspect files can inspect sockets.

  • TCP sockets provide reliable, ordered, connection-based communication. Used by web servers, SSH, databases.
  • UDP sockets are connectionless and fast but without delivery guarantees. Used by DNS, NTP, streaming.
  • Unix domain sockets are for inter-process communication on the same machine. Appear as files in the filesystem, faster than loopback TCP.
  • ss -tlnp is the most useful single command for socket inspection. Learn it and use it as your first step when troubleshooting any network connectivity problem.
  • A socket in LISTEN state means a service is ready to accept connections. ESTABLISHED means an active connection exists. TIME_WAIT and CLOSE_WAIT indicate connections in various stages of closing.
  • When a service says "address already in use", use ss -tlnp sport = :PORT to find what is occupying the port.
  • When Nginx returns 502 for a PHP-FPM backend, check the Unix socket file permissions first. The Nginx process user must have read and write access to the socket file.

Sockets are the mechanism underneath every network service you run and every connection your systems make. Understanding them makes troubleshooting faster, makes service configuration clearer, and makes the Linux networking model far less mysterious.

$_
Ready to go beyond reading? Manage Local Users and Groupsfree · auto-graded RHCSA lab, nothing to install Not sure where you stand? Take the 10-min RHCSA skill check →
Open lab →