2011-03-10 4 views
5

¿Por qué struct sockaddr contiene un campo de familia de direcciones? ¿Ya no está arreglada la familia de direcciones con la llamada al socket()?¿Por qué `struct sockaddr` contiene un campo de familia de direcciones?

+0

Supongo que el kernel solo enruta la llamada en función de la familia proporcionada en bind. Supongo que cada familia correspondería a un módulo kernel diferente. –

Respuesta

4

sockaddr se utiliza en otros lugares además de connect y bind, incluyendo los lugares en los que no tienen algún conocimiento externo de la familia de direcciones involucrados - getaddrinfo ser uno.

Además, aunque no creo que lo siguiente sea equivalente a practicar en cualquier lugar, puedo ver que ha estado en el ojo de quien diseñó esto originalmente: la llamada a socket() define la familia de protocolos. sockaddr contiene la familia de direcciones. En la práctica, creo que estos son siempre los mismos, pero teóricamente podría tener un protocolo capaz de soportar dos tipos de direcciones diferentes.

EDITAR: Hay otra forma en que el parámetro es útil. Si está utilizando sockets de datagramas (UDP) y tiene un socket en un estado "conectado" con una dirección de destino predeterminada, puede clear out that address llamando al connect() con sockaddr con sa_family con AF_UNSPEC.

+0

Hmm ... +1 para "más lugares" y la teoría PF contra AF, pero 'struct sockaddr' es anterior a' getaddrinfo' por al menos 15 años. –

+0

larsmans, he agregado un lugar que usa el parámetro y donde los métodos en cuestión han existido siempre y cuando 'struct sockaddr'. Aunque no sé si esa funcionalidad específica ha durado tanto. Aparte de ese lugar, no sé de nada más que realmente necesite a la familia y que haya existido siempre y cuando 'struct sockaddr' sí lo haya hecho. –

0

El campo sa_family se usa para indicar qué tipo de dirección será en el campo sa_data. En muchas aplicaciones, se supone que la familia de direcciones es IPV4. Sin embargo, muchas aplicaciones también son compatibles con IPV6.

+1

Pero incluso para IPv6, la familia de direcciones ya está configurada en la llamada a socket(), ¿no es así? – mdm

2

Si observas la interfaz getaddrinfo, que es la única forma correcta y moderna de convertir entre representaciones de intercambio de direcciones (nombres o direcciones numéricas) y las estructuras sockaddr, creo que verás por qué es necesaria.

Dicho esto, todo el material de struct sockaddr es un gran desastre de diseños erróneos, especialmente la conversión endian del espacio de usuario.

Otra buena instancia de por qué se necesita el campo sa_family es getsockname y getpeername interfaces. Si el programa heredó el descriptor de archivo de otro programa y aún no sabe qué tipo de socket es, debe poder determinarlo para realizar nuevas conexiones o incluso convertir la dirección en una representación adecuada para el intercambio.

+1

@R: esto también es importante para los sockets de servidores de doble pila IPv4/IPv6 para detectar si un cliente IPv4 o IPv6 está conectado. –

1

Si mira el código de red 4.2BSD, donde se originó la interfaz de los sockets, verá que el sockaddr se pasa a los controladores de la interfaz de red pero el socket fd no.

Cuestiones relacionadas