Understanding Unix Domain Sockets and a Go Implementation
This article explains Unix domain sockets as a high‑performance inter‑process communication mechanism, describes their types and workflow, outlines advantages and typical use cases, and provides a complete Go example of a server and client communicating via a Unix socket.
Unix Domain Socket Overview
Unix domain sockets are an inter‑process communication (IPC) mechanism for processes on the same host, offering higher performance than network sockets because they bypass the network protocol stack.
Types of Unix Domain Sockets
Stream sockets (SOCK_STREAM) : connection‑oriented, reliable byte‑stream service similar to TCP.
Datagram sockets (SOCK_DGRAM) : connection‑less, message‑oriented service similar to UDP.
Workflow of Unix Domain Sockets
Server‑side operations
Create socket : use a system call to obtain a socket file descriptor.
Bind socket : bind the socket to a filesystem path.
Listen : put the socket into listening state.
Accept connection : accept incoming client connections and obtain a new descriptor.
Communicate : read/write data between server and client.
Close socket : close the socket and clean up resources after communication.
Client‑side operations
Create socket : use a system call to obtain a socket file descriptor.
Connect to server : connect to the server’s socket path.
Communicate : read/write data between client and server.
Close socket : close the socket after communication.
Advantages and Typical Use Cases
Advantages
Efficiency : lower overhead and higher performance because the network stack is not involved.
Security : usable only on the local host, reducing exposure to network attacks.
Simplicity : easier configuration and use compared with network sockets.
Typical Scenarios
Local process communication : communication between system services or components of an application.
High‑performance services : low‑latency local services such as database servers (e.g., MySQL).
Container‑to‑container communication : IPC between containers in a containerized environment.
Unix domain sockets are a fast, reliable local IPC mechanism suitable for low‑latency, high‑performance applications.
Go Implementation
The article provides a Go example of a server and client using a Unix socket, along with test output demonstrating message exchange.
// TestServer testing server
func TestServer(t *testing.T) {
if _, err := os.Stat(socketPath); err == nil {
os.Remove(socketPath) // delete if exists
}
listener, err := net.Listen("unix", socketPath) // listen, create unix socket
if err != nil {
fmt.Println("listen error:", err)
return
}
defer listener.Close() // close listener
fmt.Println("service started...")
for {
conn, err := listener.Accept() // accept connection
if err != nil {
fmt.Println("accept error:", err)
return
}
go handleConnection(conn) // handle connection
}
} // handleConnection processing connection
func handleConnection(conn net.Conn) {
defer conn.Close() // close connection
buffer := make([]byte, 1024) // create buffer
n, err := conn.Read(buffer) // read data
if err != nil {
fmt.Println("read error:", err)
return
}
fmt.Printf("received message: %s\n", string(buffer[:n])) // print data
} // TestClient testing client
func TestClient(t *testing.T) {
conn, err := net.Dial("unix", socketPath)
if err != nil {
fmt.Println("dial error:", err)
return
}
defer conn.Close()
message := "Hello FunTester"
_, err = conn.Write([]byte(message))
if err != nil {
fmt.Println("write error:", err)
return
}
} Service started...
Received message: Hello FunTester
Received message: Hello FunTester
Received message: Hello FunTesterFuture versions in Java and Groovy are announced.
FunTester
10k followers, 1k articles | completely useless
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.