Яка різниця між AF_INET та PF_INET в програмуванні розеток?


205

Яка різниця між AF_INET та PF_INET в програмуванні розеток?

Я плутаюся між використанням AF_INET та PF_INET в socket()і bind().

Крім того, як вказати ip-адресу в sin_addrполі?


Просто шукайте в мережі: один результат такий
Op De Cirkel

Мені це теж цікаво. Вони, схоже, звикають взаємозамінно в дзвінках сокета серед різних кодерів.
Метт

@MattH Обидва вони однакові, як у нових ядрах Linux. Ви можете знайти те саме у відповіді герцога нижче.
СП Сандху

Відповіді:


250

Відомий посібник з мережевого програмування Beej дає приємне пояснення:

У деякій документації ви побачите згадку про містичний "PF_INET". Це дивний ефірний звір, який рідко зустрічається в природі, але я також міг би трохи прояснити це. Колись давно вважалося, що, можливо, адресна сім'я (що означає "AF" у "AF_INET") може підтримувати кілька протоколів, на які посилається їх сім'я протоколів (на що означає "PF" у "PF_INET") ).
Цього не сталося. Що ж, добре. Отже, правильним є використання AF_INET у вашій структурі sockaddr_in та PF_INET для виклику socket (). Але практично кажучи, ви можете використовувати AF_INET скрізь. І, оскільки саме це робить У. Річард Стівенс у своїй книзі, саме тут я і зроблю.


68

У вихідному коді ядра Linux я виявив, що PF_INET і AF_INET однакові. Наступний код з файлу include / linux / socket.h , рядок 204 дерева ядра Linux 3.2.21.

/* Protocol families, same as address families. */
...
#define PF_INET     AF_INET

звичайно, герцог, це те ж саме і для попередніх ядер, я маю на увазі ядра до версії 3.0?
СП Сандху

1
Наскільки я знаю, у всіх версіях ядра та libc PF_ * == AF_ *
Duke

Це правда на нелінукс-платформах?
Гарна людина

1
Я думаю, щоб переконатися, вам потрібно перевірити включений файл заголовка :)
Герцог

У Ubuntu / Debian я знайшов визначення AF у/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Петро Яворик

48
  • AF = Сімейство адрес
  • PF = сім'я протоколів

Значення, AF_INETстосується адрес з Інтернету, конкретно IP-адрес.PF_INETпосилається на що-небудь у протоколі, як правило, сокети / порти.

Поміркуйте, прочитавши підручні сторінки для socket (2) та прив’яжіть (2) . Для цього sin_addrполя просто зробіть щось таке, як встановити його:

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

дякую @codemac, я використав addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); але для чого це inet_pton ()?
СП Сандху

також для man-сторінок, коли я набираю man bind (2) або man bind (), термінал видає несподіваний маркер '(' помилка, тоді як man bind дає пояснення прив'язки в bash вбудованих. Як отримати man-сторінку для bind (). Я маю на увазі функція bind ()?
С.П. Сандху

@ jatt.beas: Синтаксис є man <section> <topic>, напр man 2 bind.
Фріріх Раабе

11

Насправді, AF_ і PF_ - це одне і те ж. Деякі слова у Вікіпедії очистять вашу плутанину

Оригінальна концепція дизайну інтерфейсу сокета розрізняє типи протоколів (сімейства) та конкретні типи адрес, які може використовувати кожен. Було передбачено, що сім'я протоколів може мати декілька типів адрес. Типи адреси визначалися додатковими символьними константами, використовуючи префікс AF_ замість PF_. Ідентифікатори AF_ призначені для всіх структур даних, які конкретно стосуються типу адреси, а не сімейства протоколів. Однак ця концепція розділення типу протоколу та адреси не знайшла підтримку впровадження, і AF_-константи були просто визначені відповідним ідентифікатором протоколу, що робить відмінність між AF_ та константами PF_ технічним аргументом без істотного практичного наслідку. Справді, існує велика плутанина при правильному використанні обох форм.


4

AF_INET = Формат адреси, Інтернет = IP адреси

PF_INET = Пакетний формат, Інтернет = IP, TCP / IP або UDP / IP

AF_INET - це сімейство адрес, яке використовується для створення сокета (у цьому випадку адреса Інтернет-протоколу). Наприклад, ядро ​​Linux підтримує 29 інших сімей адрес, таких як сокети UNIX та IPX, а також зв'язок з IRDA та Bluetooth (AF_IRDA та AF_BLUETOOTH, але сумнівно, що ви будете використовувати їх на такому низькому рівні).

Здебільшого, дотримуючись AF_INET для програмування сокетів по мережі - це найбезпечніший варіант.

Значить, AF_INET посилається на адреси з Інтернету, конкретно IP-адреси.

PF_INET посилається на що-небудь у протоколі, як правило, сокети / порти.


3

Бувають ситуації, коли це має значення.

Якщо ви передасте AF_INET до socket() в Cygwin, ваш розетку може бути, а може і не бути випадковим чином скинутий. Передача PF_INET забезпечує правильне з'єднання.

Cygwin само-правда величезний безлад для програмування сокетів, але це реальний світ випадок , коли AF_INET і PF_INET не є ідентичними.


6
Будь ласка, поясніть. Я знаходжу #define PF_INET AF_INETв Cygwin's socket.h.
Маркіз Лорн

3

Перевірка проблеми заголовка вирішує проблему. Можна перевірити наявність компілятора системи.

Для моєї системи AF_INET == PF_INET

AF == Сім'я адрес та PF == Сім'я протоколів

Сімейства протоколів, такі ж, як адреси сімей.

введіть тут опис зображення


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.