В чем разница между константами AF_INET и PF_INET?
Если посмотреть на примеры программирования сокетов, мы увидим, что некоторые люди используют AF_INET
, а другие используют PF_INET
. Кроме того, иногда оба они используются в том же примере. Вопрос в том, есть ли разница между ними? Какой из них мы должны использовать?
Если вы можете ответить на этот вопрос, другой вопрос будет... Почему существуют две одинаковые (но равные) константы?
То, что я обнаружил, пока:
socket
manpage
В программировании сокетов (Unix) у нас есть функция socket()
, которая получает следующие параметры:
int socket(int domain, int type, int protocol);
В manpage говорится:
Аргумент domain
указывает домен связи; это выбирает семейство протоколов, которое будет использоваться для связи. Эти семьи определены в < sys/socket.h > .
И manpage цитирует AF_INET
, а также некоторые другие константы AF_
для параметра domain
. Кроме того, в разделе NOTES
той же man-страницы мы можем прочитать:
Константы манифеста, используемые под 4.x BSD для семейств протоколов, являются PF_UNIX, PF_INET и т.д., Тогда как AF_UNIX и т.д. Используются для семейств адресов. Однако уже личная страница BSD promises: "Семейство протоколов как правило, совпадает с семейством адресов", а последующие стандарты используйте AF_ * везде.
Заголовки C
sys/socket.h
фактически не определяет эти константы, а включает bits/socket.h
. Этот файл определяет около 38 констант AF_
и 38 PF_
констант, подобных этому:
#define PF_INET 2 /* IP protocol family. */
#define AF_INET PF_INET
Python
Python socket module очень похож на C API. Однако существует много констант AF_
, но только одна константа PF_
(PF_PACKET). Таким образом, в Python у нас нет выбора, кроме использования AF_INET
.
Я думаю, что это решение включить только константы AF_
следует одному из руководящих принципов: "Должен быть один - и желательно только один - простой способ сделать это". (Zen of Python)
Дополнительная информация
Этот пост форума ссылки на это старое сообщение, который содержит некоторую историческую информацию.
Ответы
Ответ 1
Я думаю, что заметки Википедии об этом подводит итог:
Оригинальная концепция дизайна интерфейса сокета, выделяемая между типами протоколов (семействами) и конкретными типами адресов, которые могут использовать каждый. Предполагалось, что семейство протоколов может иметь несколько типов адресов. Типы адресов определялись дополнительными символическими константами, используя префикс AF_
вместо PF_
. Идентификаторы AF_
предназначены для всех структур данных, которые специфически относятся к типу адреса, а не к семейству протоколов. Однако эта концепция разделения типа протокола и адреса не нашла поддержки реализации, а константы AF_
были просто определены с помощью соответствующего идентификатора протокола, делая различие между константами AF_
versus PF_
техническим аргументом без значительных практическое следствие. Действительно, существует большая путаница в правильном использовании обеих форм.
Даже если кто-то придумал причину разницы сегодня, им придется придумать новые идентификаторы или так много вещей сломается...