Linux nazwał gniazda howto

38

Wiem, że w Linuksie są nazwane gniazda i nazwane potoki (fifo).

W ls -l, będą wyglądać jak poniżej: (I zostały zmienione nazwy plików, do demonstracji).

prw-r--r-- 1 root root 0 Nov  8 16:31 /tmp/fifo
srwxrwxrwx 1 root root 0 Nov  8 15:54 /tmp/socket

Teraz można utworzyć nazwaną potok za pomocą mkfifo. Czy istnieje polecenie utworzenia nazwanego gniazda?

Ostatnią opcją byłoby napisanie programu w C, który wywołałby funkcję mknod, ale chciałby wiedzieć, czy istnieje już taka komenda.

Co próbowałem:
Próbowałem wyszukać dowolne opcje mknod i mkfifo, ale nie znalazłem.

UWAGA: Nie mówię o modelu serwer-klient przez Ethernet / sieć. Nazwany plik gniazda będzie używany przez 2 procesy w tym samym systemie.

anishsane
źródło
2
Tylko uwaga: mam 2 procesy - qemu i virsh, które mogą ze sobą rozmawiać za pomocą nazwanego gniazda (zgodnie z moim zrozumieniem na podstawie dokumentacji). Ale nie wiem, jak utworzyć nazwane gniazdo. Chociaż istnieją inne opcje używania virsh z qemu, szukałem opcji, w której mogę dołączyć virsh do istniejącego procesu qemu i potrzebuje on nazwanego gniazda podczas uruchamiania procesu qemu. Nazwany fifo nie działa. Poza tym myślę, że ciekawie będzie wiedzieć, jak utworzyć nazwane gniazdo, na wypadek, gdyby było później potrzebne.
anishsane

Odpowiedzi:

24

Plik gniazda Unix / Linux jest zasadniczo dwukierunkowym FIFO. Ponieważ gniazda zostały pierwotnie utworzone jako sposób zarządzania komunikacją sieciową, można nimi manipulować za pomocą wywołań systemowych send()i recv(). Jednak w uniksowym duchu „wszystko jest plikiem” możesz także używać write()i read(). Musisz użyć socketpair()lub, socket()aby utworzyć nazwane gniazda. Samouczek dotyczący korzystania z gniazd w C można znaleźć tutaj: Przewodnik Beej po Unix IPC: Unix Sockets .

Narzędzie socatwiersza poleceń jest przydatne, gdy chcesz bawić się gniazdami bez pisania „prawdziwego” programu. Jest podobny netcati działa jako adapter między różnymi interfejsami sieciowymi i interfejsami plików.

Spinki do mankietów:

Joakim Nohlgård
źródło
1
socketpair () lub socket () tworzy nienazwane gniazdo, które będzie użyteczne tylko z poziomu programu C.
anishsane
Warto byłoby sprawdzić, czy można utworzyć nazwane gniazdo za pomocą socat. Prawdopodobnie stwórz nienazwane gniazdo, powiąż je z localhost: some_port, a następnie użyj socat z tym portem?
anishsane
3
Możliwe jest tworzenie nazwanych gniazd za socatpomocą polecenia UNIX-LISTEN, zobacz man socatlub ten podręcznik HTML
Joakim Nohlgård
1
Próbowałem to szybki i brudny polecenia i utworzony plik gniazda f1: socat UNIX-LISTEN:f1 LISTEN:f2.
Totor
1
Jest ukryty w szczegółach witryny socat, ale w przypadku, gdy jest to pomocne, istnieje składnia do traktowania dwóch jednokierunkowych nazwanych potoków (fifo) jako pojedynczej jednostki dwukierunkowej, którą można połączyć z innymi jednostkami dwukierunkowymi, takimi jak gniazda Unix lub TCP. Do nazwanych potoków dołączasz za pomocą !!(socat 1.x) lub %(socat 2.x), pisząc nazwany potok po lewej stronie i czytając nazwany potok po prawej stronie. np.socat 'PIPE:/tmp/outstream!!PIPE:/tmp/instream' UNIX-CONNECT:/tmp/mysocket
Ivan X
17

Utwórz szybko gniazdo w pythonie:

~]# python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('/tmp/somesocket')"
~]# ll /tmp/somesocket 
srwxr-xr-x. 1 root root 0 Mar  3 19:30 /tmp/somesocket

Lub za pomocą małego programu C , np. Zapisz następujące elementy w create-a-socket.c:

#include <fcntl.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    // The following line expects the socket path to be first argument
    char * mysocketpath = argv[1];
    // Alternatively, you could comment that and set it statically:
    //char * mysocketpath = "/tmp/mysock";
    struct sockaddr_un namesock;
    int fd;
    namesock.sun_family = AF_UNIX;
    strncpy(namesock.sun_path, (char *)mysocketpath, sizeof(namesock.sun_path));
    fd = socket(AF_UNIX, SOCK_DGRAM, 0);
    bind(fd, (struct sockaddr *) &namesock, sizeof(struct sockaddr_un));
    close(fd);
    return 0;
}

Następnie zainstaluj gcc, skompiluj go i ta-da:

~]# gcc -o create-a-socket create-a-socket.c
~]# ./create-a-socket mysock
~]# ll mysock
srwxr-xr-x. 1 root root 0 Mar  3 17:45 mysock
rsaw
źródło
1

Nie ma narzędzia linii poleceń do tworzenia gniazd, ponieważ gniazdo jest zawsze łączone z serwerem, który obsługuje żądania wysłane do tego gniazda.

Będziesz musiał napisać serwer i pozwolić temu stworzyć gniazdo. Oto samouczek .

Aaron Digulla
źródło
To nadal byłoby nienazwane gniazdo. Chcę utworzyć gniazdo, które byłoby używane przez 2 inne procesy, jako dwukierunkowe fifo.
anishsane
Sprawdź link w mojej odpowiedzi. Pokazuje, jak skonfigurować bind()połączenie"/home/beej/mysocket"
Aaron Digulla,