В чем разница между AF_INET и PF_INET в программировании сокетов?

205

В чем разница между AF_INET и PF_INET в программировании сокетов?

Я запутался между использованием AF_INET и PF_INET в socket()иbind() .

Кроме того, как дать IP-адрес в sin_addrполе?

ИП Санду
источник
Просто поищите в сети: один результат этого
Op De Cirkel
Мне тоже интересно это. Кажется, они взаимозаменяемы при вызове сокетов между разными кодерами.
Мэтт
@MattH Они оба такие же, как в новых ядрах Linux. Вы можете найти то же самое в ответе герцога ниже.
С.П. Санду

Ответы:

250

Знаменитое руководство Биджа по сетевому программированию дает хорошее объяснение:

В какой-то документации вы увидите упоминание о мистическом «PF_INET». Это странное эфирное чудовище, которое редко встречается в природе, но я мог бы также пояснить это немного здесь. Когда-то давно считалось, что, возможно, семейство адресов (что означает «AF» в «AF_INET») может поддерживать несколько протоколов, на которые ссылается их семейство протоколов (что означает «PF» в «PF_INET») ).
Этого не случилось. Ну что ж. Поэтому правильное решение - использовать AF_INET в вашей структуре sockaddr_in и PF_INET в вашем вызове socket (). Но практически вы можете использовать AF_INET везде. И, поскольку именно это У. Ричард Стивенс делает в своей книге, именно этим я и буду заниматься здесь.

Damon
источник
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
Это правда на не Linux платформах?
Хороший человек
1
Я думаю, чтобы убедиться, что вы должны проверить включенный заголовочный файл :)
Duke
В Ubuntu / Debian я нашел определения AF в/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Петр Яворик,
48
  • AF = Адрес семьи
  • PF = Семейство протоколов

AF_INETИмеется в виду, относится к адресам из Интернета, в частности, к IP-адресам. PF_INETотносится к чему-либо в протоколе, обычно к сокетам / портам.

Попробуйте прочитать справочные страницы для socket (2) и bind (2) . Для sin_addrполя просто сделайте что-то вроде следующего, чтобы установить его:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 
codemac
источник
спасибо @codemac, я использовал addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); но для чего нужен inet_pton ()?
С.П. Санду
также для man-страниц, когда я набираю man bind (2) или man bind (), терминал выдает неожиданный токен '(' error, тогда как man bind дает объяснение bind во встроенных командах bash. Как получить man-страницу для bind (). Я имею в виду функция bind ()?
С.П. Сандху
@ jatt.beas: Синтаксис является man <section> <topic>, например man 2 bind.
Фрерих Раабе
11

На самом деле AF_ и PF_ - это одно и то же. Есть несколько слов в Википедии, чтобы очистить вашу путаницу

Первоначальная концепция дизайна интерфейса сокетов различалась между типами протоколов (семействами) и конкретными типами адресов, которые каждый может использовать. Предполагалось, что семейство протоколов может иметь несколько типов адресов. Типы адресов были определены дополнительными символическими константами, используя префикс AF_ вместо PF_. AF_-идентификаторы предназначены для всех структур данных, которые конкретно относятся к типу адреса, а не к семейству протоколов. Однако эта концепция разделения протокола и типа адреса не нашла поддержки реализации, и константы AF_ были просто определены соответствующим идентификатором протокола, что делает различие между константами AF_ и PF_ техническим аргументом, не имеющим значительных практических последствий. Действительно, существует много путаницы в правильном использовании обеих форм.

FIRO
источник
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 относится к чему-либо в протоколе, обычно к сокетам / портам.

DINO U
источник
3

Есть ситуации, когда это имеет значение.

Если вы передадите AF_INET socket() в Cygwin, ваш сокет может или не может быть случайно сброшен. Передача PF_INET гарантирует, что соединение работает правильно.

Cygwin само-правда огромный беспорядок для программирования сокетов, но это реальный мир случай , когда AF_INET и PF_INET не являются идентичными.

FlyingJester
источник
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