В чем разница между 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
поле?
Ответы:
Знаменитое руководство Биджа по сетевому программированию дает хорошее объяснение:
В какой-то документации вы увидите упоминание о мистическом «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) и bind (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