¿Cuál es la diferencia entre AF_INET y PF_INET en la programación de socket?
Estoy confundido entre usar AF_INET y PF_INET en socket()
y bind()
.
Además, ¿cómo dar la dirección IP en el sin_addr
campo?
¿Cuál es la diferencia entre AF_INET y PF_INET en la programación de socket?
Estoy confundido entre usar AF_INET y PF_INET en socket()
y bind()
.
Además, ¿cómo dar la dirección IP en el sin_addr
campo?
Respuestas:
La famosa guía de programación de red de Beej da una buena explicación:
En alguna documentación, verá una mención de un místico "PF_INET". Esta es una extraña bestia etérea que rara vez se ve en la naturaleza, pero también podría aclararlo un poco aquí. Hace mucho tiempo, se pensó que tal vez una familia de direcciones (lo que significa "AF" en "AF_INET") podría admitir varios protocolos a los que hizo referencia su familia de protocolos (lo que significa "PF" en "PF_INET" )
Eso no sucedió. Oh bien. Entonces, lo correcto es usar AF_INET en su struct sockaddr_in y PF_INET en su llamada a socket (). Pero prácticamente hablando, puedes usar AF_INET en todas partes. Y, como eso es lo que W. Richard Stevens hace en su libro, eso es lo que haré aquí.
Encontré en el código fuente del kernel de Linux que PF_INET y AF_INET son iguales. El siguiente código es del archivo include / linux / socket.h , línea 204 del árbol Linux kernel 3.2.21.
/* Protocol families, same as address families. */
...
#define PF_INET AF_INET
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Es decir, se AF_INET
refiere a direcciones de Internet, direcciones IP específicamente. PF_INET
se refiere a cualquier cosa en el protocolo, generalmente sockets / puertos.
Considere leer las páginas de manual para socket (2) y bind (2) . Para el sin_addr
campo, simplemente haga algo como lo siguiente para configurarlo:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
, por ejemplo man 2 bind
.
De hecho, AF_ y PF_ son lo mismo. Hay algunas palabras en Wikipedia que aclararán tu confusión.
El concepto de diseño original de la interfaz de socket distinguía entre los tipos de protocolo (familias) y los tipos de dirección específicos que cada uno puede usar. Se imaginó que una familia de protocolos puede tener varios tipos de direcciones. Los tipos de dirección se definieron mediante constantes simbólicas adicionales, utilizando el prefijo AF_ en lugar de PF_. Los identificadores AF_ están destinados a todas las estructuras de datos que tratan específicamente con el tipo de dirección y no con la familia de protocolos. Sin embargo, este concepto de separación de protocolo y tipo de dirección no ha encontrado soporte de implementación y las constantes AF_ simplemente se definieron por el identificador de protocolo correspondiente, lo que hace que la distinción entre las constantes AF_ versus PF_ sea un argumento técnico sin consecuencias prácticas significativas. De hecho, existe mucha confusión en el uso adecuado de ambas formas.
AF_INET = Formato de dirección, Internet = Direcciones IP
PF_INET = Formato de paquete, Internet = IP, TCP / IP o UDP / IP
AF_INET es la familia de direcciones que se utiliza para el socket que está creando (en este caso, una dirección de Protocolo de Internet). El kernel de Linux, por ejemplo, admite otras 29 familias de direcciones, como sockets UNIX e IPX, y también comunicaciones con IRDA y Bluetooth (AF_IRDA y AF_BLUETOOTH, pero es dudoso que las use en un nivel tan bajo).
En su mayor parte, seguir con AF_INET para la programación de sockets en una red es la opción más segura.
Es decir, AF_INET se refiere a direcciones de internet, específicamente a direcciones IP.
PF_INET se refiere a cualquier cosa en el protocolo, generalmente sockets / puertos.
Hay situaciones en las que importa.
Si pasa AF_INET a socket()
Cygwin, su socket puede o no restablecerse aleatoriamente. Pasar PF_INET asegura que la conexión funcione correctamente.
Cygwin es un gran desastre para la programación de sockets, pero es un caso del mundo real donde AF_INET y PF_INET no son idénticos.
#define PF_INET AF_INET
en Cygwin's socket.h
.
La comprobación del archivo de encabezado resuelve el problema. Uno puede verificar si hay compilador del sistema.
Para mi sistema, AF_INET == PF_INET
AF == Familia de direcciones y PF == Familia de protocolos
Protocolo de familias, igual que las familias de direcciones.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h