que - Comprender INADDR_ANY para la programación de socket
sockaddr_in (5)
Estoy intentando programar algunos sockets y, por lo tanto, en el lado del servidor, uso htonl(INADDR_ANY)
. En la medida en que lo entendí, me parece que esta función genera una IP aleatoria (¿estoy en lo cierto?). De hecho, quiero vincular mi socket con mi localhost
. Pero si ejecuto esto
printf("%d",htonl(INADDR_ANY));
Obtengo 0 como valor de retorno. ¿Podría alguien traer alguna explicación?
bind () de INADDR_ANY NO "genera una IP aleatoria". Vincula el socket a todas las interfaces disponibles .
Para un servidor, normalmente desea vincularse a todas las interfaces, no solo a "localhost".
Si desea vincular su socket a localhost solamente, la sintaxis sería
my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
, luego llame abind(my_socket, (SOCKADDR *) &my_sockaddr, ...)
.Como sucede, "INADDR_ANY" es una constante que pasa a ser igual a "cero":
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 ...
Si aún no está familiarizado con esto, le recomiendo que consulte la Guía de la Programación de Enchufes de Beej:
Como las personas todavía están leyendo esto, una nota adicional:
Cuando un proceso desea recibir nuevos paquetes o conexiones entrantes, debe vincular un socket a una dirección de interfaz local utilizando bind(2) .
En este caso, solo un socket IP puede estar vinculado a cualquier par local (dirección, puerto). Cuando se especifica INADDR_ANY en la llamada de enlace, el socket se vinculará a todas las interfaces locales.
Cuando se listen(2) en un socket desconectado, el socket se vincula automáticamente a un puerto libre aleatorio con la dirección local establecida en INADDR_ANY.
Cuando se llama a connect(2) en un socket no vinculado, el socket se vincula automáticamente a un puerto libre aleatorio oa un puerto compartido utilizable con la dirección local establecida en INADDR_ANY ...
Hay varias direcciones especiales: INADDR_LOOPBACK (127.0.0.1) siempre se refiere al host local a través del dispositivo loopback; INADDR_ANY (0.0.0.0) significa cualquier dirección para vincular ...
También:
bind () - Vincula un nombre a un socket :
Si el campo (sin_addr.s_addr) se establece en la constante INADDR_ANY, tal como se define en netinet / in.h, el llamante solicita que el socket se vincule a todas las interfaces de red en el host. Posteriormente, los paquetes UDP y las conexiones TCP de todas las interfaces (que coinciden con el nombre enlazado) se enrutan a la aplicación. Esto se vuelve importante cuando un servidor ofrece un servicio a múltiples redes. Al dejar la dirección sin especificar, el servidor puede aceptar todos los paquetes UDP y las solicitudes de conexión TCP realizadas para su puerto, independientemente de la interfaz de red a la que llegaron las solicitudes.
INADDR_ANY es una constante, que contiene 0 en valor. esto se usará solo cuando desee conectarse desde todos los puertos activos que no le interesan ip-add. así que si quieres conectar cualquier ip particular, debes mencionar como my_sockaddress.sin_addr.s_addr = inet_addr ("192.168.78.2")
Para enlazar socket con localhost , antes de invocar la función de vinculación, el campo sin_addr.s_addr de la estructura sockaddr_in debe establecerse correctamente. El valor adecuado se puede obtener ya sea por
my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")
o por
my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
INADDR_ANY
ordena que el socket de escucha se enlace a todas las interfaces disponibles. Es lo mismo que intentar enlazar con inet_addr("0.0.0.0")
. Para completar, también mencionaré que también hay IN6ADDR_ANY_INIT para IPv6 y es lo mismo que intentar enlazar a ::
dirección para socket IPv6.
#include <netinet/in.h>
struct in6_addr addr = IN6ADDR_ANY_INIT;
Además, tenga en cuenta que al vincular el zócalo IPv6 a IN6ADDR_ANY_INIT
su zócalo se vinculará a todas las interfaces IPv6 y también podrá aceptar conexiones de clientes IPv4 (aunque direcciones mapeadas IPv6).
INADDR_ANY
se usa cuando no necesita vincular un socket a una IP específica. Cuando utiliza este valor como la dirección al llamar a bind()
, el socket acepta conexiones a todas las direcciones IP de la máquina.