2010-03-16 22 views
8
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <stdio.h> 

void error(char *msg) 
{ 
    perror(msg); 
    exit(0); 
} 
int main(int argc, char *argv[]) 
{ 
    int sock, length, fromlen, n; 
    struct sockaddr_in6 server; 
    struct sockaddr_in6 from; 

    int portNr = 5555; 
    char buf[1024]; 

    length = sizeof (struct sockaddr_in6); 

    sock=socket(AF_INET6, SOCK_DGRAM, 0); 
    if (sock < 0) error("Opening socket"); 

    bzero((char *)&server, length); 
    server.sin6_family=AF_INET6; 
    server.sin6_addr=in6addr_any; 
    server.sin6_port=htons(portNr); 

    inet_pton(AF_INET6, "fe80::21f:29ff:feed:2f7e", (void *)&server.sin6_addr.s6_addr); 
    //inet_pton(AF_INET6, "::1", (void *)&server.sin6_addr.s6_addr); 

    if (bind(sock,(struct sockaddr *)&server,length)<0) 
     error("binding"); 
    fromlen = sizeof(struct sockaddr_in6); 
    while (1) { 
     n = recvfrom(sock,buf,1024,0,(struct sockaddr *)&from,&fromlen); 
     if (n < 0) error("recvfrom"); 
     write(1,"Received a datagram: ",21); 
     write(1,buf,n); 
     n = sendto(sock,"Got your message\n",17, 
        0,(struct sockaddr *)&from,fromlen); 
     if (n < 0) error("sendto"); 
    } 
} 

cuando compilar y ejecutar el código anterior que tengo:Por qué no puedo enlazar socket IPv6 a una dirección de enlace local

binding: Invalid argument 

y si el cambio de obligar a la ::1 y dejo otra cosa sin cambios en el código fuente, el código funciona! Entonces, ¿podrías decirme qué pasa con mi código? gracias por adelantado.

Respuesta

13

Para obtener las direcciones de enlace local, también es necesario especificar el ID de ámbito de la interfaz de red que se asocia con la dirección ... algo como esto:

server.sin6_scope_id = 5; /* or whatever the scope ID is for the network interface you want to communicate over */ 

Puede utilizar getifaddrs() para encontrar los diversos identificadores de alcance disponibles en sus sistemas, y las interfaces de red a las que corresponden.

(Sí, es un problema ... como alternativa, podría agregar algo como "% en0" al final de la cadena que pasa a inet_pton(), y inet_pton() podría hacer el trabajo por usted. .. No estoy seguro de si inet_pton() maneja esa sintaxis o no)

+3

inet_pton no maneja% si se añaden cadenas. Puede usar getaddrinfo para trabajar con% de las representaciones de cadenas de direcciones ip6 adjuntas. Ver la página man http://linux.die.net/man/3/getaddrinfo –

Cuestiones relacionadas