Jaka jest różnica między AF_INET i PF_INET w programowaniu gniazd?


205

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_addrpolu?


Wystarczy wyszukać w sieci: jeden wynik jest taki
Op De Cirkel

Zastanawiam się nad tym. Wydaje się, że są używane zamiennie w wywołaniu gniazda między różnymi koderami.
Matt

@MattH Oba są takie same jak w nowych jądrach Linuksa. To samo możesz znaleźć w odpowiedzi Duke'a poniżej.
SP Sandhu,

Odpowiedzi:


250

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.


68

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

na pewno Duke, czy to samo dotyczy poprzednich jąder, mam na myśli jądra sprzed wersji 3.0?
SP Sandhu,

1
O ile wiem, we wszystkich wersjach jądra i libc PF_ * == AF_ *
Duke

Czy to prawda na platformach innych niż Linux?
Dobra osoba,

1
Myślę, że dla pewności należy sprawdzić dołączony plik nagłówka :)
Duke

Na Ubuntu / Debian znalazłem definicje AF w/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik

48
  • AF = rodzina adresów
  • PF = rodzina protokołów

Znaczenie, AF_INETodnosi się do adresów z Internetu, w szczególności adresów IP. PF_INETodnosi się do czegokolwiek w protokole, zwykle gniazd / portów.

Rozważ przeczytanie stron podręcznika man dla socket (2) i bind (2) . Aby sin_addrustawić pole, wykonaj następujące czynności:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 

dzięki @codemac, użyłem addr.sin_addr.s_addr = inet_addr („127.0.0.1”); ale do czego służy inet_pton ()?
SP Sandhu,

także dla stron man, kiedy piszę man bind (2) lub man bind (), terminal daje nieoczekiwany token '(' błąd, podczas gdy man bind wyjaśnia objaśnienie wbudowanych bashów. Jak uzyskać stronę man dla bind (). funkcja bind ()?
SP Sandhu

@ jatt.beas: Składnia jest man <section> <topic>np man 2 bind.
Frerich Raabe

11

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.


4

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.


3

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.


6
Proszę wytłumacz. Znajduję #define PF_INET AF_INETu Cygwina socket.h.
Markiz Lorne

3

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.

wprowadź opis zdjęcia tutaj


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.