Яка різниця між AF_INET та PF_INET в програмуванні розеток?
Я плутаюся між використанням AF_INET та PF_INET в socket()
і bind()
.
Крім того, як вказати ip-адресу в sin_addr
полі?
Яка різниця між AF_INET та PF_INET в програмуванні розеток?
Я плутаюся між використанням AF_INET та PF_INET в socket()
і bind()
.
Крім того, як вказати ip-адресу в sin_addr
полі?
Відповіді:
Відомий посібник з мережевого програмування Beej дає приємне пояснення:
У деякій документації ви побачите згадку про містичний "PF_INET". Це дивний ефірний звір, який рідко зустрічається в природі, але я також міг би трохи прояснити це. Колись давно вважалося, що, можливо, адресна сім'я (що означає "AF" у "AF_INET") може підтримувати кілька протоколів, на які посилається їх сім'я протоколів (на що означає "PF" у "PF_INET") ).
Цього не сталося. Що ж, добре. Отже, правильним є використання AF_INET у вашій структурі sockaddr_in та PF_INET для виклику socket (). Але практично кажучи, ви можете використовувати AF_INET скрізь. І, оскільки саме це робить У. Річард Стівенс у своїй книзі, саме тут я і зроблю.
У вихідному коді ядра 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
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Значення, 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);
man <section> <topic>
, напр man 2 bind
.
Насправді, AF_ і PF_ - це одне і те ж. Деякі слова у Вікіпедії очистять вашу плутанину
Оригінальна концепція дизайну інтерфейсу сокета розрізняє типи протоколів (сімейства) та конкретні типи адрес, які може використовувати кожен. Було передбачено, що сім'я протоколів може мати декілька типів адрес. Типи адреси визначалися додатковими символьними константами, використовуючи префікс AF_ замість PF_. Ідентифікатори AF_ призначені для всіх структур даних, які конкретно стосуються типу адреси, а не сімейства протоколів. Однак ця концепція розділення типу протоколу та адреси не знайшла підтримку впровадження, і AF_-константи були просто визначені відповідним ідентифікатором протоколу, що робить відмінність між AF_ та константами PF_ технічним аргументом без істотного практичного наслідку. Справді, існує велика плутанина при правильному використанні обох форм.
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 посилається на що-небудь у протоколі, як правило, сокети / порти.
Бувають ситуації, коли це має значення.
Якщо ви передасте AF_INET до socket()
в Cygwin, ваш розетку може бути, а може і не бути випадковим чином скинутий. Передача PF_INET забезпечує правильне з'єднання.
Cygwin само-правда величезний безлад для програмування сокетів, але це реальний світ випадок , коли AF_INET і PF_INET не є ідентичними.
#define PF_INET AF_INET
в Cygwin's socket.h
.
Перевірка проблеми заголовка вирішує проблему. Можна перевірити наявність компілятора системи.
Для моєї системи AF_INET == PF_INET
AF == Сім'я адрес та PF == Сім'я протоколів
Сімейства протоколів, такі ж, як адреси сімей.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h