2010-09-17 11 views
7

Harici bir bileşenin bana IP adresi içeren bir dize ilettiği bir programım var. O zaman bunu bir URI'ye dönüştürmem gerekiyor. IPv4 için bu kolay; Http: // 'yi ekliyorum ve/ekliyorum. Ancak, IPv6 için de onu parantez içine almam gerekiyor [].Bir metin dizesinin standart C soketleri API'sini kullanarak bir IPv6 adresi veya IPv4 adresi olup olmadığını belirtin.

Adresin adres ailesini belirlemek için standart bir yuva API çağrısı var mı?

+0

Soket API'sinin bir parçası olmadığını biliyorum, ancak IP4 ve IP6 tek olasılıksa, bunu strlen ile yapamaz mısınız? ;-) –

+0

@Steve Jessop, ör. ff02 :: 2 ve 8.8.8.8 – nos

+0

@nos: yeterince adil, eski geçerli bir adres olduğunu bilmiyordum. Daha genel olarak, dizeleri incelemek için bir yol var mı, bu soket API'yi kullanmaktan daha basit bir kod mu? Bu durumda ayrıştırılmış adresi içeren yapıya gerek yoktur. –

cevap

13

Kullanım getaddrinfo() ve getaddrinfo gelen başarılı dönüşünde ipucu bayrak AI_NUMERICHOST, AF_UNSPEC aileyi, set, .ai_family üyesi addrinfo çıkan yapı ya AF_INET veya AF_INET6'dan olacaktır.

DÜZENLEME, küçük örnek

#include <sys/types.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netdb.h> 

int main(int argc, char *argv[]) 
{ 
    struct addrinfo hint, *res = NULL; 
    int ret; 

    memset(&hint, '\0', sizeof hint); 

    hint.ai_family = PF_UNSPEC; 
    hint.ai_flags = AI_NUMERICHOST; 

    ret = getaddrinfo(argv[1], NULL, &hint, &res); 
    if (ret) { 
     puts("Invalid address"); 
     puts(gai_strerror(ret)); 
     return 1; 
    } 
    if(res->ai_family == AF_INET) { 
     printf("%s is an ipv4 address\n",argv[1]); 
    } else if (res->ai_family == AF_INET6) { 
     printf("%s is an ipv6 address\n",argv[1]); 
    } else { 
     printf("%s is an is unknown address format %d\n",argv[1],res->ai_family); 
    } 

    freeaddrinfo(res); 
    return 0; 
} 

$ ./a.out 127.0.0.1 
127.0.0.1 is an ipv4 address 
$ ./a.out ff01::01 
ff01::01 is an ipv6 address 
16

tür. İlk olarak bir IPv4 (AF_INET) IPv6 (AF_INET6) olarak dizeyi ayrıştırmayı denemek için inet_pton() kullanabilirsiniz. Dönüş kodu, işlev başarılı olursa sizi bilgilendirir ve dize, girişilen türün bir adresini içerir. Örneğin

:

#include <arpa/inet.h> 
#include <stdio.h> 

static int 
ip_version(const char *src) { 
    char buf[16]; 
    if (inet_pton(AF_INET, src, buf)) { 
     return 4; 
    } else if (inet_pton(AF_INET6, src, buf)) { 
     return 6; 
    } 
    return -1; 
} 

int 
main(int argc, char *argv[]) { 
    for (int i = 1; i < argc; ++i) { 
     printf("%s\t%d\n", argv[i], ip_version(argv[i])); 
    } 

    return 0; 
} 
+1

getaddrinfo() 'nın bir demet yükü vardır fakat temel olarak inet_pton() işlevini de çağırır. inet_pton() gerçekten ihtiyacınız olan tek şey ve bu soruya en iyi yanıtı IMHO. Ayrıca bir temizleme işlevi gerektirmez. – rockdaboot

İlgili konular