Unix Domain Sockets: Unterschied zwischen den Versionen
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…“ |
PhilKa (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| Zeile 184: | Zeile 184: | ||
socklen_t len = sizeof(client); | socklen_t len = sizeof(client); | ||
recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, &len); | recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, &len); | ||
printf(" | printf("Empfangen: %s\n", buf); | ||
sendto(fd, "Antwort vom Server", 18, 0, (struct sockaddr*)&client, len); | |||
</syntaxhighlight> | |||
Client: | |||
<syntaxhighlight lang="c"> | |||
int fd; | |||
struct sockaddr_un addr, srv; | |||
char buf[100]; | |||
fd = socket(AF_UNIX, SOCK_DGRAM, 0); | |||
addr.sun_family = AF_UNIX; | |||
strcpy(addr.sun_path, "/tmp/client_dgram.sock"); | |||
unlink(addr.sun_path); | |||
bind(fd, (struct sockaddr*)&addr, sizeof(addr)); | |||
srv.sun_family = AF_UNIX; | |||
strcpy(srv.sun_path, "/tmp/server_dgram.sock"); | |||
sendto(fd, "Hallo Server", 12, 0, (struct sockaddr*)&srv, sizeof(srv)); | |||
recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL); | |||
printf("Antwort: %s\n", buf); | |||
</syntaxhighlight> | |||
--- | |||
== Zugriffsschutz == | |||
Unix Domain Sockets nutzen das **Dateisystem-Rechtesystem**. | |||
Nur Prozesse mit ausreichenden Rechten (z. B. Besitzer, Gruppe, `chmod`-Berechtigungen) dürfen sich verbinden. | |||
Das macht sie sicherer als Netzwerk-Sockets für lokale Kommunikation. | |||
--- | |||
== Leistung == | |||
Da keine Protokollkonvertierung (IP, Routing, Checksummen etc.) notwendig ist, sind Unix Domain Sockets **deutlich schneller** als TCP/IP-Sockets auf demselben Rechner. | |||
Sie erreichen Übertragungsraten ähnlich wie anonyme Pipes oder Shared Memory, bieten aber zugleich **vollwertige bidirektionale Kommunikation**. | |||
--- | |||
== Unterschiede zu TCP/IP-Sockets == | |||
{| class="wikitable" | |||
! Merkmal !! Unix Domain Socket !! TCP/IP Socket | |||
|- | |||
| Namensraum || Dateipfad || IP-Adresse + Port | |||
|- | |||
| Reichweite || nur lokal || systemübergreifend | |||
|- | |||
| Sicherheit || durch Dateirechte || durch Firewalls/Netzwerkebene | |||
|- | |||
| Geschwindigkeit || sehr hoch || langsamer (Netzwerk-Stack) | |||
|- | |||
| Protokoll || kein IP/Transport-Layer || TCP oder UDP | |||
|- | |||
| Debugging || via `ls`, `lsof` || via `netstat`, `ss` | |||
|} | |||
--- | |||
== Einsatzgebiete == | |||
* Kommunikation zwischen **Daemon** und **Client** (z. B. <code>systemd</code>, <code>dbus</code>) | |||
* **Datenbanken** (z. B. PostgreSQL, MySQL) | |||
* **Container-Kommunikation** (z. B. Docker Socket: <code>/var/run/docker.sock</code>) | |||
* **Lokale IPC** zwischen GUI-Programmen und Hintergrunddiensten | |||
--- | |||
== Vorteile == | |||
* Sehr schnell und effizient | |||
* Sicherheit über UNIX-Dateisystemrechte | |||
* Keine Netzwerkkonfiguration nötig | |||
* Unterstützt alle Socket-APIs (send, recv, select, poll, etc.) | |||
== Nachteile == | |||
* Nur lokale Kommunikation | |||
* Kein Routing über Netzwerk | |||
* Dateipfade müssen verwaltet und ggf. gelöscht werden | |||
--- | |||
== Siehe auch == | |||
* [[Socket (Programmierung)]] | |||
* [[TCP (Protokoll)]] | |||
* [[UDP (Protokoll)]] | |||
* [[Interprozesskommunikation (IPC)]] | |||
* [[Named Pipe (FIFO)]] | |||
* [[POSIX Threads]] | |||
* [[Systemaufrufe unter Unix]] | |||
--- | |||
== Quellen == | |||
* Stevens, W. Richard: ''UNIX Network Programming, Vol. 1'', Prentice Hall | |||
* IEEE Std 1003.1 (POSIX) – Sockets API | |||
* Linux Man Pages: <code>man 7 unix</code>, <code>man 2 socket</code> | |||
* GNU C Library Documentation | |||
* The Linux Programming Interface – Michael Kerrisk, 2010 | |||
Version vom 21. Oktober 2025, 15:00 Uhr
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:
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("Empfangen: %s\n", buf);
sendto(fd, "Antwort vom Server", 18, 0, (struct sockaddr*)&client, len);
Client:
int fd;
struct sockaddr_un addr, srv;
char buf[100];
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/tmp/client_dgram.sock");
unlink(addr.sun_path);
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
srv.sun_family = AF_UNIX;
strcpy(srv.sun_path, "/tmp/server_dgram.sock");
sendto(fd, "Hallo Server", 12, 0, (struct sockaddr*)&srv, sizeof(srv));
recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
printf("Antwort: %s\n", buf);
---
Zugriffsschutz
Unix Domain Sockets nutzen das **Dateisystem-Rechtesystem**. Nur Prozesse mit ausreichenden Rechten (z. B. Besitzer, Gruppe, `chmod`-Berechtigungen) dürfen sich verbinden. Das macht sie sicherer als Netzwerk-Sockets für lokale Kommunikation.
---
Leistung
Da keine Protokollkonvertierung (IP, Routing, Checksummen etc.) notwendig ist, sind Unix Domain Sockets **deutlich schneller** als TCP/IP-Sockets auf demselben Rechner. Sie erreichen Übertragungsraten ähnlich wie anonyme Pipes oder Shared Memory, bieten aber zugleich **vollwertige bidirektionale Kommunikation**.
---
Unterschiede zu TCP/IP-Sockets
| Merkmal | Unix Domain Socket | TCP/IP Socket |
|---|---|---|
| Namensraum | Dateipfad | IP-Adresse + Port |
| Reichweite | nur lokal | systemübergreifend |
| Sicherheit | durch Dateirechte | durch Firewalls/Netzwerkebene |
| Geschwindigkeit | sehr hoch | langsamer (Netzwerk-Stack) |
| Protokoll | kein IP/Transport-Layer | TCP oder UDP |
| Debugging | via `ls`, `lsof` | via `netstat`, `ss` |
---
Einsatzgebiete
- Kommunikation zwischen **Daemon** und **Client** (z. B.
systemd,dbus) - **Datenbanken** (z. B. PostgreSQL, MySQL)
- **Container-Kommunikation** (z. B. Docker Socket:
/var/run/docker.sock) - **Lokale IPC** zwischen GUI-Programmen und Hintergrunddiensten
---
Vorteile
- Sehr schnell und effizient
- Sicherheit über UNIX-Dateisystemrechte
- Keine Netzwerkkonfiguration nötig
- Unterstützt alle Socket-APIs (send, recv, select, poll, etc.)
Nachteile
- Nur lokale Kommunikation
- Kein Routing über Netzwerk
- Dateipfade müssen verwaltet und ggf. gelöscht werden
---
Siehe auch
- Socket (Programmierung)
- TCP (Protokoll)
- UDP (Protokoll)
- Interprozesskommunikation (IPC)
- Named Pipe (FIFO)
- POSIX Threads
- Systemaufrufe unter Unix
---
Quellen
- Stevens, W. Richard: UNIX Network Programming, Vol. 1, Prentice Hall
- IEEE Std 1003.1 (POSIX) – Sockets API
- Linux Man Pages:
man 7 unix,man 2 socket - GNU C Library Documentation
- The Linux Programming Interface – Michael Kerrisk, 2010