Skip to main content

Introduction to Linux Unix Domain Sockets(UDS)

·702 words·4 mins
Linux UDS
Table of Contents

What is a Unix Domain Socket (UDS)
#

Unix Domain Socket (UDS) is an inter-process communication (IPC) mechanism in Linux/Unix systems. Unlike traditional TCP/IP sockets, UDS is used exclusively for communication between processes on the same host, bypassing the network protocol stack, which results in higher efficiency and lower latency. It communicates through a special file in the filesystem (typically a socket file), providing reliable bidirectional data transmission.

UDS supports two communication modes:

  • Stream (SOCK_STREAM): Similar to TCP, it provides connection-oriented, reliable data stream transmission.
  • Datagram (SOCK_DGRAM): Similar to UDP, it provides connectionless, unreliable datagram transmission.

Advantages of UDS
#

  1. High Performance: By avoiding the network protocol stack, UDS offers higher communication efficiency than TCP/IP sockets, especially for high-frequency, small-data scenarios.
  2. Security: UDS leverages filesystem permissions, allowing access control through Linux file permissions, enhancing security.
  3. Simplicity: No need to configure IP addresses or ports; only a file path is required.
  4. Versatility: In addition to regular data, UDS supports transferring file descriptors, credentials, and more.

Use Cases for UDS
#

UDS is widely used in Linux systems for inter-process communication, such as:

  • Local Service Communication: For example, communication between database clients and servers (e.g., MySQL).
  • System Services: Services like D-Bus and X11 use UDS for efficient communication.
  • Microservices Architecture: Communication between microservices on the same host to reduce network overhead.

Simple Example: Using UDS for Communication
#

Below is a simple C language example demonstrating how to use UDS for communication between a client and a server. The server listens for client messages and responds with a confirmation.

Server Code
#

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define SOCKET_PATH "/tmp/my_uds_socket"
#define BUFFER_SIZE 256

int main() {
    int server_fd, client_fd;
    struct sockaddr_un server_addr, client_addr;
    char buffer[BUFFER_SIZE];
    socklen_t client_len = sizeof(client_addr);

    // Create UDS socket
    server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("Socket creation failed");
        exit(1);
    }

    // Set server address
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

    // Bind socket
    unlink(SOCKET_PATH); // Remove old socket file
    if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("Bind failed");
        exit(1);
    }

    // Listen for connections
    if (listen(server_fd, 5) == -1) {
        perror("Listen failed");
        exit(1);
    }

    printf("Server listening on %s\n", SOCKET_PATH);

    // Accept client connection
    client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
    if (client_fd == -1) {
        perror("Accept failed");
        exit(1);
    }

    // Receive and respond to messages
    while (1) {
        int len = recv(client_fd, buffer, BUFFER_SIZE, 0);
        if (len <= 0) break;
        buffer[len] = '\0';
        printf("Received: %s\n", buffer);

        const char *response = "Message received!";
        send(client_fd, response, strlen(response), 0);
    }

    // Cleanup
    close(client_fd);
    close(server_fd);
    unlink(SOCKET_PATH);
    return 0;
}

Client Code
#

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define SOCKET_PATH "/tmp/my_uds_socket"
#define BUFFER_SIZE 256

int main() {
    int client_fd;
    struct sockaddr_un server_addr;
    char buffer[BUFFER_SIZE];

    // Create UDS socket
    client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_fd == -1) {
        perror("Socket creation failed");
        exit(1);
    }

    // Set server address
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

    // Connect to server
    if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("Connect failed");
        exit(1);
    }

    // Send message
    const char *message = "Hello, UDS Server!";
    send(client_fd, message, strlen(message), 0);

    // Receive server response
    int len = recv(client_fd, buffer, BUFFER_SIZE, 0);
    buffer[len] = '\0';
    printf("Server response: %s\n", buffer);

    // Cleanup
    close(client_fd);
    return 0;
}

How to Run
#

  1. Compile the server and client code:
    gcc server.c -o server
    gcc client.c -o client
    
  2. Run the server:
    ./server
    
  3. In another terminal, run the client:
    ./client
    

Upon running, the server will receive the “Hello, UDS Server!” message from the client and respond with “Message received!”.

Notes
#

  1. File Path: Ensure the SOCKET_PATH has appropriate permissions and is not occupied by other processes.
  2. Cleanup: The server should remove old socket files (using unlink) before starting to avoid binding failures.
  3. Error Handling: In production, implement robust error handling to manage connection interruptions or data anomalies.

Conclusion
#

Unix Domain Sockets are an efficient and reliable tool for inter-process communication in Linux systems, particularly suited for low-latency, high-security local communication scenarios. With simple file path configuration and robust filesystem permission support, UDS plays a critical role in system development. I hope this blog helps you better understand and utilize UDS!

Related

Intel Next Gen Xeon Specifications Emerge Featuring 192 P Cores
·929 words·5 mins
Granite Rapids Diamond Rapids Oak Stream
VxWorks 7 vxbus Device Specific Parameters
·578 words·3 mins
VxWorks 7 VxBus
How to Install Apache MySQL PHP (LAMP Stack) on Ubuntu 24.04
·613 words·3 mins
Ubuntu 24.04 Apache MySQL PHP