Hier ein kleiner Unix-Domain-Server und ein dazugehöriger Client. Sollte für den Anfang hilfreich sein. :-)
uclient.c
Code:
/***
* uclient.c - Einfacher Client für Unix-Domain-Sockets
*
* Verbindet sich mit dem ./sample-socket Unix Domain Socket,
* kopiert stdin in den Socket und beendet sich dann.
***/
#include <sys/socket.h> /* connect(), bind(), listen(), accept() */
#include <sys/un.h> /* sockaddr_un */
#include <unistd.h> /* unlink() */
#include "sockutil.h"
int main(void)
{
struct sockaddr_un address;
int sock;
size_t addrLength;
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
die("socket");
address.sun_family = AF_UNIX;
strcpy(address.sun_path, "./sample-socket");
/***
* Länge der Adresse inklusive Grösse des sun_family Elements
***/
addrLength = sizeof(address.sun_family) + strlen(address.sun_path);
if(connect(sock, (struct sockaddr *) &address, addrLength))
die("connect");
copyData(0, sock);
close(sock);
return 0;
}
userver.c
Code:
/***
* userver.c - Einfacher Server für Unix-Domain-Sockets
*
* Wartet auf eine Verbindung am ./sample-socket Unix Domain Socket.
* Ist die Verbindung hergestellt, werden alle Daten von diesem Socket
* nach stdout kopiert, bis die Verbindung vom anderen Ende geschlossen
* wird, dann warten auf neue Verbindung.
***/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "sockutil.h"
int main(void)
{
struct sockaddr_un address;
int sock, conn;
size_t addrLength;
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
die("socket");
/***
* Berets vorhandene(n) Socket/Datei entfernen
***/
unlink("./sample-socket");
address.sun_family = AF_UNIX;
strcpy(address.sun_path, "./sample-socket");
/***
* Länge der Adresse inklusive Grösse des sun_family-Elements
***/
addrLength = sizeof(address.sun_family) + strlen(address.sun_path);
if(bind(sock, (struct sockaddr *) &address, addrLength))
die("bind");
if(listen(sock, 5))
die("listen");
while((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) >= 0){
printf("---- Hole Daten ----\n");
copyData(conn, 1);
printf("---- Fertig ----\n");
close(conn);
}
if(conn < 0)
die("accept");
close(sock);
return 0;
}
Unix-Domain-Sockets haben eine einzigartige Fähigkeit: Mit ihnen können Dateideskripotren übergeben werden. Ein Prozess kann dadurch eine Datei öffnen und deren Dateideskriptor an einen anderen - möglicherweise völlig beliebigen -Prozess weitergeben. Die Zugriffsrechte werden nur beim Öffnen der Datei berücksichtigt, so dass der den Dateideskriptor erhaltende Prozess die gleichen Rechte auf die Datei erhält wie der Ursprungsprozess.
Für die Übergabe von Dateideskriptoren sind die Funktionen
Code:
#include <sys/socket.h>
int sendmsg(int fd, const struct msghdr * msg, unsigned int flags);
int recvmsg(int fd, const struct msghdr * msg, unsigned int flags);
zuständig.
Lesezeichen