¿Cuál es la diferencia entre AF_INET y PF_INET en la programación de socket?


205

¿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_addrcampo?


Solo busque en la red: un resultado es este
Op De Cirkel

Me he estado preguntando esto también. Parece que se usan indistintamente en la llamada de socket entre diferentes codificadores.
Matt

@MattH Ambos son iguales a los nuevos Kernels de Linux. Puedes encontrar lo mismo en la respuesta de Duke a continuación.
SP Sandhu

Respuestas:


250

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í.


68

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

Claro Duke, ¿es lo mismo para los núcleos anteriores también, me refiero a los núcleos anteriores a la versión 3.0?
SP Sandhu

1
Por lo que sé, en todas las versiones de kernel y libc, PF_ * == AF_ *
Duke

¿Es esto cierto en plataformas no Linux?
Buena persona

1
Creo que para asegurarme, debe verificar el archivo de encabezado incluido :)
Duke

En Ubuntu / Debian encontré definiciones de AF en/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik

48
  • AF = Familia de direcciones
  • PF = familia de protocolos

Es decir, se AF_INETrefiere a direcciones de Internet, direcciones IP específicamente. PF_INETse 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_addrcampo, simplemente haga algo como lo siguiente para configurarlo:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 

gracias @codemac, he usado addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); pero para que sirve inet_pton ()?
SP Sandhu

también para las páginas man, cuando escribo man bind (2) o man bind (), el terminal da un token inesperado '(' error, mientras que man bind da una explicación de bind en bash builtins. Cómo obtener la página man para bind (). bind () function?
SP Sandhu

@ jatt.beas: la sintaxis es man <section> <topic>, por ejemplo man 2 bind.
Frerich Raabe

11

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.


4

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.


3

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.


66
Por favor explique. Lo encuentro #define PF_INET AF_INETen Cygwin's socket.h.
Marqués de Lorne

3

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.

ingrese la descripción de la imagen aquí


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.