table of contents
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 (niewydane) |