我有一個程序,其中一個外部組件向我傳遞一個包含IP地址的字符串。然後我需要把它變成一個URI。對於IPv4來說,這很容易;我預先安裝http://並附加/。但是,對於IPv6,我還需要將它括在括號[]中。使用標準C socket告訴文本字符串是IPv6地址還是IPv4地址API
是否有標準套接字API調用來確定地址的地址族?
我有一個程序,其中一個外部組件向我傳遞一個包含IP地址的字符串。然後我需要把它變成一個URI。對於IPv4來說,這很容易;我預先安裝http://並附加/。但是,對於IPv6,我還需要將它括在括號[]中。使用標準C socket告訴文本字符串是IPv6地址還是IPv4地址API
是否有標準套接字API調用來確定地址的地址族?
使用getaddrinfo(),並設置標誌暗示AI_NUMERICHOST,家庭AF_UNSPEC,在從的getaddrinfo全成返回,所產生的結構addrinfo中.ai_family構件將或者AF_INET或AF_INET6。
EDIT,小例子
#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
類。您可以使用inet_pton()
嘗試首先將字符串解析爲IPv4(AF_INET
),然後是IPv6(AF_INET6
)。返回代碼將讓您知道函數是否成功,並且字符串因此包含嘗試類型的地址。
例如:
#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;
}
getaddrinfo()有一堆開銷,但基本上也調用inet_pton()。 inet_pton()真的是你所需要的,恕我直言,這個問題的最佳答案。它也不需要清理功能。 – rockdaboot 2014-08-20 08:46:59
這裏有一個簡單的函數來做到這一點:
http://tdistler.com/2011/02/25/how-to-test-if-an-address-is-ipv4-or-ipv6
它也將處理主機名字符串,返回返回的第一個DNS條目的地址類型。設置AI_NUMERICHOST來禁用主機名。
我知道它不是套接字API的一部分,但是如果IP4和IP6是唯一的可能性,你不能用'strlen'來做這個嗎? ;-) – 2010-09-17 16:43:48
@Steve Jessop考慮例如ff02 :: 2和8.8.8.8 – nos 2010-09-17 17:41:32
@nos:夠公平的,沒有意識到前者是一個有效的地址。更一般地說,是否有一些方法來檢查字符串,這比使用套接字API更簡單的代碼?在這種情況下,不需要包含解析地址的結構。 – 2010-09-17 17:51:16