bind(2) | System Calls Manual | bind(2) |
NAZWA
bind - przywiązuje nazwę do gniazda
BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)
SKŁADNIA
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
OPIS
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.
WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu zwracane jest zero. Po błędzie zwracane jest -1 i ustawiane errno, wskazując błąd.
BŁĘDY
- EACCES
- Adres jest chroniony, a użytkownik nie jest superużytkownikiem.
- EADDRINUSE
- Podany adres już jest wykorzystywany.
- EADDRINUSE
- (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).
- EBADF
- sockfd nie jest prawidłowym deskryptorem pliku.
- EINVAL
- Gniazdo jest już skojarzone z adresem.
- EINVAL
- addrlen jest nieprawidłowe lub addr nie jest prawidłowym adresem dla tej domeny gniazda.
- ENOTSOCK
- Deskryptor pliku sockfd nie odnosi się do gniazda.
Następujące błędy odnoszą się do gniazd domeny UNIX-owej (AF_UNIX):
- EACCES
- Brak praw do przeszukiwania dla składowej ścieżki (zob. także path_resolution(7)).
- EADDRNOTAVAIL
- Zażądano nieistniejącego interfejsu lub żądany adres nie jest adresem lokalnym.
- EFAULT
- addr wskazuje poza dostępną dla użytkownika przestrzeń adresową.
- ELOOP
- Podczas rozwiązywania addr napotkano zbyt wiele dowiązań symbolicznych.
- ENAMETOOLONG
- addr jest zbyt długie.
- ENOENT
- Fragment ścieżki gniazda odnoszący się do któregoś z katalogów nie istnieje.
- ENOMEM
- Brak pamięci jądra.
- ENOTDIR
- Składowa ścieżki nie jest katalogiem.
- EROFS
- I-węzeł gniazda rezyduje na systemie plików przeznaczonym tylko do odczytu.
STANDARDY
POSIX.1-2008.
HISTORIA
POSIX.1-2001, SVr4, 4.4BSD (bind() pojawiło się pierwotnie w 4.2BSD).
USTERKI
Nie opisano opcji przezroczystych proxy.
PRZYKŁADY
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"); }
ZOBACZ TAKŻE
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)
TŁUMACZENIE
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 |