Подтвердить что ты не робот

Понимание INADDR_ANY для программирования сокетов

Я пытаюсь запрограммировать некоторые сокеты, поэтому на стороне сервера я использую htonl(INADDR_ANY). Насколько я понял, мне кажется, что эта функция генерирует случайный IP (правильно ли я?). На самом деле, я хочу связать мой сокет с моим localhost. Но если я запустил этот

printf("%d",htonl(INADDR_ANY));

Я получаю 0 в качестве возвращаемого значения. Может кто-нибудь принести какое-то объяснение?

4b9b3361

Ответ 1

  1. bind() INADDR_ANY НЕ "генерирует случайный IP". Он связывает сокет со всеми доступными интерфейсами.

  2. Для сервера обычно требуется привязка ко всем интерфейсам, а не только к локальному хосту.

  3. Если вы хотите привязать свой сокет только к локальному хосту, синтаксисом будет my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1"); , затем вызовите bind(my_socket, (SOCKADDR *) &my_sockaddr,...).

  4. Как это бывает, "INADDR_ANY" - это константа, которая оказывается равной "нулю":

    http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html

    # define INADDR_ANY ((unsigned long int) 0x00000000)
    ...
    # define INADDR_NONE    0xffffffff
    ...
    # define INPORT_ANY 0
    ...
    
  5. Если вы еще не знакомы с этим, я настоятельно рекомендую вам ознакомиться с Beej Guide to Sockets Programming:

    http://beej.us/guide/bgnet/

Поскольку люди все еще читают это, дополнительная заметка:

мужчина (7) ip:

Когда процесс хочет получать новые входящие пакеты или соединения, он должен привязать сокет к адресу локального интерфейса, используя bind (2).

В этом случае только один IP-сокет может быть привязан к любой локальной (адрес, порт). Когда INADDR_ANY указывается в вызове bind, сокет будет привязан ко всем локальным интерфейсам.

Когда вызов (2) вызывается на несвязанный сокет, сокет автоматически привязывается к произвольному свободному порту с локальным адресом, установленным в INADDR_ANY.

Когда вызов connect (2) вызывается на несвязанный сокет, сокет автоматически привязан к произвольному свободному порту или к используемому совместно используемому порту с локальным адресом, установленным в INADDR_ANY...

Существует несколько специальных адресов: INADDR_LOOPBACK (127.0.0.1) всегда ссылается на локальный хост через устройство loopback; INADDR_ANY (0.0.0.0) означает любой адрес для привязки...

Также:

bind() - привязать имя к сокету:

Если поле (sin_addr.s_addr) установлено в константу INADDR_ANY, как определено в netinet/in.h, вызывающий абонент запрашивает, чтобы сокет был привязан ко всем сетевым интерфейсам на хосте. Впоследствии UDP-пакеты и TCP-соединения из всех интерфейсов (которые соответствуют имени привязки) направляются в приложение. Это становится важным, когда сервер предлагает услугу для нескольких сетей. Если оставить адрес не указанным, сервер может принимать все UDP-пакеты и запросы TCP-соединения, сделанные для своего порта, независимо от сетевого интерфейса, по которому были получены запросы.

Ответ 2

INADDR_ANY используется, когда вам не нужно связывать сокет с определенным IP-адресом. Когда вы используете это значение в качестве адреса при вызове bind(), сокет принимает подключения ко всем IP-адресам устройства.

Ответ 3

Чтобы связать сокет с localhost, перед вызовом функции bind, необходимо установить значение поля sin_addr.s_addr структуры sockaddr_in. Собственное значение может быть получено либо через

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")

или

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

Ответ 4

INADDR_ANY - это константа, содержащая значение 0. это будет использоваться только тогда, когда вы хотите подключиться со всех активных портов, вас не интересует ip-add. поэтому, если вы хотите подключить какой-либо конкретный ip, вы должны упомянуть как my_sockaddress.sin_addr.s_addr = inet_addr ( "192.168.78.2" )

Ответ 5

INADDR_ANY инструктирует прослушивающий сокет привязываться ко всем доступным интерфейсам. Он аналогичен попытке привязки к inet_addr("0.0.0.0"). Для полноты я также упомянул, что есть также IN6ADDR_ANY_INIT для IPv6, и он аналогичен попытке привязки к :: адресу для сокета IPv6.

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

Также обратите внимание, что при IN6ADDR_ANY_INIT сокета IPv6 к IN6ADDR_ANY_INIT ваш сокет будет привязываться ко всем интерфейсам IPv6 и должен также принимать соединения от клиентов IPv4 (хотя и с адресами, сопоставленными IPv6).