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

Linux下tcpdump介绍
·826 words·4 mins
Linux Tcpdump
Linux下使用IPMI批量管理服务器BMC
·346 words·2 mins
Linux Bcm Ipmi
使用 find 命令高效查找文件
·157 words·1 min
Linux Find