Jaka jest różnica między AF_INET i PF_INET w programowaniu gniazd?
Nie jestem pewien, czy mogę używać AF_INET i PF_INET w socket()
i bind()
.
Ponadto, jak podać adres IP w sin_addr
polu?
Jaka jest różnica między AF_INET i PF_INET w programowaniu gniazd?
Nie jestem pewien, czy mogę używać AF_INET i PF_INET w socket()
i bind()
.
Ponadto, jak podać adres IP w sin_addr
polu?
Odpowiedzi:
Słynny przewodnik programistyczny Beej daje ładne wyjaśnienie:
W niektórych dokumentach zobaczysz wzmiankę o mistycznym „PF_INET”. To dziwna, eteryczna bestia, którą rzadko widuje się w naturze, ale równie dobrze mogę ją tutaj wyjaśnić. Dawno, dawno temu sądzono, że być może rodzina adresów (co oznacza „AF” w „AF_INET”) może obsługiwać kilka protokołów, do których odwołuje się ich rodzina protokołów (co oznacza „PF” w „PF_INET” ).
To się nie stało. No cóż. Więc poprawne jest użycie AF_INET w swojej strukturze sockaddr_in i PF_INET w wywołaniu funkcji socket (). Ale praktycznie można używać AF_INET wszędzie. A ponieważ to właśnie robi W. Richard Stevens w swojej książce, właśnie to zrobię tutaj.
W kodzie źródłowym jądra systemu Linux znalazłem, że PF_INET i AF_INET są takie same. Poniższy kod pochodzi z pliku include / linux / socket.h , wiersz 204 drzewa jądra Linux 3.2.21.
/* Protocol families, same as address families. */
...
#define PF_INET AF_INET
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Znaczenie, AF_INET
odnosi się do adresów z Internetu, w szczególności adresów IP. PF_INET
odnosi się do czegokolwiek w protokole, zwykle gniazd / portów.
Rozważ przeczytanie stron podręcznika man dla socket (2) i bind (2) . Aby sin_addr
ustawić pole, wykonaj następujące czynności:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
np man 2 bind
.
W rzeczywistości AF_ i PF_ są tym samym. W Wikipedii jest kilka słów, które rozwiążą twoje wątpliwości
Oryginalna koncepcja projektowania interfejsu gniazda rozróżniała typy protokołów (rodziny) od konkretnych typów adresów, z których każdy może korzystać. Przewidywano, że rodzina protokołów może mieć kilka typów adresów. Typy adresów zostały zdefiniowane przez dodatkowe stałe symboliczne, używając przedrostka AF_ zamiast PF_. Identyfikatory AF_ są przeznaczone dla wszystkich struktur danych, które dotyczą konkretnie typu adresu, a nie rodziny protokołów. Jednak ta koncepcja separacji typu protokołu i adresu nie znalazła wsparcia dla implementacji, a stałe AF_ zostały po prostu zdefiniowane przez odpowiedni identyfikator protokołu, co czyni rozróżnienie między stałymi AF_ i PF_ technicznym argumentem bez istotnych praktycznych konsekwencji. Rzeczywiście, istnieje duże zamieszanie w prawidłowym stosowaniu obu form.
AF_INET = format adresu, Internet = adresy IP
PF_INET = Format pakietu, Internet = IP, TCP / IP lub UDP / IP
AF_INET to rodzina adresów używana dla tworzonego gniazda (w tym przypadku adres protokołu internetowego). Na przykład jądro Linux obsługuje 29 innych rodzin adresów, takich jak gniazda UNIX i IPX, a także komunikację z IRDA i Bluetooth (AF_IRDA i AF_BLUETOOTH, ale wątpliwe jest, abyś używał ich na tak niskim poziomie).
W większości przypadków trzymanie się AF_INET do programowania gniazd przez sieć jest najbezpieczniejszą opcją.
Oznacza to, że AF_INET odnosi się do adresów z Internetu, w szczególności adresów IP.
PF_INET odnosi się do wszystkiego w protokole, zwykle gniazd / portów.
Są sytuacje, w których ma to znaczenie.
Jeśli przekażesz AF_INET do socket()
w Cygwin, twoje gniazdo może zostać losowo zresetowane. Przekazywanie PF_INET zapewnia prawidłowe działanie połączenia.
Cygwin sam przyznaje, że to ogromny bałagan w programowaniu gniazd, ale jest to rzeczywisty przypadek, w którym AF_INET i PF_INET nie są identyczne.
#define PF_INET AF_INET
u Cygwina socket.h
.
Sprawdzanie, czy plik nagłówkowy rozwiązuje problem. Można tam sprawdzić kompilator systemowy.
W moim systemie AF_INET == PF_INET
AF == Rodzina adresów i PF == Rodzina protokołów
Rodziny protokołów, takie same jak rodziny adresów.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h