bind(2) System Calls Manual bind(2)

bind - przywiązuje nazwę do gniazda

Standardowa biblioteka C (libc, -lc)

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
         socklen_t addrlen);

Gdy tworzone jest gniazdo za pomocą socket(2), istnieje ono w przestrzeni nazw (rodzinie adresów), lecz nie ma przypisanego adresu. bind() przypisuje adres określony w addr do gniazda odnoszącego się do deskryptora pliku sockfd. addrlen określa rozmiar, w bajtach, struktury adresowej na którą wskazuje addr. Tradycyjnie operacja ta była nazywana "przypisaniem nazwy do gniazda".

Normalnie, zanim gniazdo SOCK_STREAM będzie mogło odbierać połączenia (zobacz accept(2)), niezbędne jest przypisanie mu lokalnego adresu za pomocą bind().

Reguły dotyczące przywiązywania nazw są różne w różnych rodzinach adresów. Szczegółowe informacje znajdują się na stronach podręcznika systemowego w sekcji 7. Dla AF_INET zobacz ip(7), dla AF_INET6 zobacz ipc6(7), dla AF_UNIX zobacz unix(7), dla AF_APPLETALK zobacz ddp(7), dla AF_PACKET zobacz packet(7), dla AF_X25 zobacz x25(7), a dla AF_NETLINK zobacz netlink(7).

Faktyczna struktura przekazywana jako argument addr będzie zależała od rodziny adresowej. Struktura sockaddr jest zdefiniowana podobnie do:


struct sockaddr {
    sa_family_t sa_family;
    char        sa_data[14];
}

Jedyną funkcją tej struktury jest rzutowanie wskaźnika struktury przekazanego w addr, aby uniknąć ostrzeżeń kompilatora. Zob. PRZYKŁADY poniżej.

Po pomyślnym zakończeniu zwracane jest zero. Po błędzie zwracane jest -1 i ustawiane errno, wskazując błąd.

Adres jest chroniony, a użytkownik nie jest superużytkownikiem.
Podany adres już jest wykorzystywany.
(gniazda domeny Internet) Podano zero jako numer portu w strukturze adresu gniazda, lecz przy próbie skojarzenia z portem dynamicznym (efemerycznym), okazało się, że wszystkie numery portów w zakresie portów dynamicznych są aktualnie używane. Więcej informacji w opisie pliku /proc/sys/net/ipv4/ip_local_port_range w podręczniku ip(7).
sockfd nie jest prawidłowym deskryptorem pliku.
Gniazdo jest już skojarzone z adresem.
addrlen jest nieprawidłowe lub addr nie jest prawidłowym adresem dla tej domeny gniazda.
Deskryptor pliku sockfd nie odnosi się do gniazda.

Następujące błędy odnoszą się do gniazd domeny UNIX-owej (AF_UNIX):

Brak praw do przeszukiwania dla składowej ścieżki (zob. także path_resolution(7)).
Zażądano nieistniejącego interfejsu lub żądany adres nie jest adresem lokalnym.
addr wskazuje poza dostępną dla użytkownika przestrzeń adresową.
Podczas rozwiązywania addr napotkano zbyt wiele dowiązań symbolicznych.
addr jest zbyt długie.
Fragment ścieżki gniazda odnoszący się do któregoś z katalogów nie istnieje.
Brak pamięci jądra.
Składowa ścieżki nie jest katalogiem.
I-węzeł gniazda rezyduje na systemie plików przeznaczonym tylko do odczytu.

POSIX.1-2008.

POSIX.1-2001, SVr4, 4.4BSD (bind() pojawiło się pierwotnie w 4.2BSD).

Nie opisano opcji przezroczystych proxy.

Przykładowy program używający bind() z gniazdami domeny Internet można znaleźć w getaddrinfo(3).

Następujący przykład pokazuje sposób na skojarzenie gniazda strumieniowego w domenie uniksowej (AF_UNIX) i akceptować połączenia:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define MY_SOCK_PATH "/somepath"
#define LISTEN_BACKLOG 50
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(void)
{
    int                 sfd, cfd;
    socklen_t           peer_addr_size;
    struct sockaddr_un  my_addr, peer_addr;
    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        handle_error("socket");
    memset(&my_addr, 0, sizeof(my_addr));
    my_addr.sun_family = AF_UNIX;
    strncpy(my_addr.sun_path, MY_SOCK_PATH,
            sizeof(my_addr.sun_path) - 1);
    if (bind(sfd, (struct sockaddr *) &my_addr,
             sizeof(my_addr)) == -1)
        handle_error("bind");
    if (listen(sfd, LISTEN_BACKLOG) == -1)
        handle_error("listen");
    /* Teraz możemy akceptować nadchodzące połączenia,
       po jednym naraz, za pomocą accept(2). */
    peer_addr_size = sizeof(peer_addr);
    cfd = accept(sfd, (struct sockaddr *) &peer_addr,
                 &peer_addr_size);
    if (cfd == -1)
        handle_error("accept");
    /* Kod do obsługi nadchodzących połączeń... */
    if (close(sfd) == -1)
        handle_error("close");
    if (unlink(MY_SOCK_PATH) == -1)
        handle_error("unlink");
}

accept(2), connect(2), getsockname(2), listen(2), socket(2), getaddrinfo(3), getifaddrs(3), ip(7), ipv6(7), path_resolution(7), socket(7), unix(7)

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.

2 maja 2024 r. Linux man-pages 6.8