Unix Domain Sockets

Aus dev.kaibel.net
Version vom 21. Oktober 2025, 14:59 Uhr von PhilKa (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „= Unix Domain Sockets = '''Unix Domain Sockets''' (auch '''Local Sockets''' oder '''AF_UNIX-Sockets''') sind eine Form der Interprozesskommunikation (IPC) unter Unix-ähnlichen Betriebssystemen (Linux, macOS, BSD). Im Gegensatz zu Internet-Sockets (z. B. TCP/UDP über IPv4 oder IPv6) ermöglichen Unix Domain Sockets eine **schnelle und sichere Kommunikation zwischen Prozessen auf demselben System**. --- == Grundprinzip == Unix Domain Sockets verwende…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Unix Domain Sockets

Unix Domain Sockets (auch Local Sockets oder AF_UNIX-Sockets) sind eine Form der Interprozesskommunikation (IPC) unter Unix-ähnlichen Betriebssystemen (Linux, macOS, BSD). Im Gegensatz zu Internet-Sockets (z. B. TCP/UDP über IPv4 oder IPv6) ermöglichen Unix Domain Sockets eine **schnelle und sichere Kommunikation zwischen Prozessen auf demselben System**.

---

Grundprinzip

Unix Domain Sockets verwenden das Dateisystem als Namensraum: Jeder Socket wird durch einen **Dateipfad** (z. B. /tmp/socket) repräsentiert.

Prozesse können über diesen Pfad eine Verbindung aufbauen und bidirektional Daten austauschen – ähnlich wie über Netzwerk-Sockets, jedoch **ohne Netzwerkprotokoll-Overhead**.

+-------------+             +-------------+
|  Prozess A  | <---------> |  Prozess B  |
| (Client)    |             | (Server)    |
+-------------+             +-------------+
          \                   /
           \_________________/
             Unix Domain Socket (/tmp/demo.sock)

---

Eigenschaften

  • Kommunikation **nur lokal** (kein Routing über Netzwerke)
  • Sehr **geringe Latenz** und **hohe Geschwindigkeit**
  • Unterstützt **Stream (SOCK_STREAM)** und **Datagram (SOCK_DGRAM)**-Typen
  • Nutzung von **Dateisystemrechten** zur Zugriffskontrolle
  • Ermöglicht **Dateideskriptor-Weitergabe** (Advanced IPC)

---

Socket-Typen

Typ Beschreibung Entspricht
SOCK_STREAM zuverlässige, verbindungsorientierte Kommunikation ähnlich wie TCP
SOCK_DGRAM verbindungslos, Nachrichten-orientiert ähnlich wie UDP
SOCK_SEQPACKET sequenziell, aber paketorientiert Hybridform

---

Header und Adressstruktur

#include <sys/socket.h>
#include <sys/un.h>

Adresse einer Unix-Socket-Verbindung:

struct sockaddr_un {
    sa_family_t sun_family;    // AF_UNIX
    char sun_path[108];        // Pfadname des Sockets
};

---

Beispiel 1: Server mit Unix Domain Stream Socket

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

#define SOCKET_PATH "/tmp/unix_demo.sock"

int main() {
    int server_fd, client_fd;
    struct sockaddr_un addr;
    char buffer[128];

    unlink(SOCKET_PATH); // alten Socket-Pfad löschen

    if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

    if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, 5) == -1) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    printf("Server wartet auf Verbindung...\n");
    client_fd = accept(server_fd, NULL, NULL);
    if (client_fd == -1) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    read(client_fd, buffer, sizeof(buffer));
    printf("Nachricht vom Client: %s\n", buffer);

    const char* reply = "Hallo vom Server!";
    write(client_fd, reply, strlen(reply));

    close(client_fd);
    close(server_fd);
    unlink(SOCKET_PATH); // Socket-Datei entfernen
    return 0;
}

---

Beispiel 2: Client

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

#define SOCKET_PATH "/tmp/unix_demo.sock"

int main() {
    int sock;
    struct sockaddr_un addr;
    char buffer[128];

    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    const char* message = "Hallo Server!";
    write(sock, message, strlen(message));

    int n = read(sock, buffer, sizeof(buffer) - 1);
    buffer[n] = '\0';
    printf("Antwort vom Server: %s\n", buffer);

    close(sock);
    return 0;
}

---

Beispiel 3: Datagram-Variante (SOCK_DGRAM)

Bei SOCK_DGRAM ist keine Verbindung nötig. Client und Server tauschen Nachrichten ähnlich wie UDP aus.

Server: <syntaxhighlight lang="c"> int fd; struct sockaddr_un addr; char buf[100];

fd = socket(AF_UNIX, SOCK_DGRAM, 0); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, "/tmp/server_dgram.sock"); unlink(addr.sun_path); bind(fd, (struct sockaddr*)&addr, sizeof(addr));

struct sockaddr_un client; socklen_t len = sizeof(client); recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, &len); printf("Empfange