在IPV6大势所趋下,我们不得不考虑扩展现有的程序,让它也支持ipv6。本篇主要针对socket下ipv4到ipv6的移植相关内容。
一、区别之处
1)地址结构
ipv4地址结构:
struct sockaddr_in {
short int sin_family; //地址族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //地址
unsigned char sin_zero[8];
};
struct in_addr {
unsigned long s_addr;
};
ipv6地址结构:
struct sockaddr_in6{
uint8_t sin6_len; //IPv6 为固定的(9php.com)24 字节长度
sa_family_t sin6_family; //地址簇类型,为AF_INET6
in_port_t sin6_port; //16 位端口号,网络字节序
uint32_t sin6_flowinfo; //32 位流标签
struct in6_addr sin6_addr; //128 位IP 地址
}
举例:
ipv4地址赋值:
rcv_udp_addr.sin_family = AF_INET;
rcv_udp_addr.sin_addr.s_addr = htonl(INADDR_ANY);
rcv_udp_addr.sin_port = htons(UDPRCV_PORT);
ipv6地址赋值:
rcv_udp_addr.sin6_family = PF_INET6;
rcv_udp_addr.sin6_addr = in6addr_any;
rcv_udp_addr.sin6_port = htons(UDPRCV_PORT);
注意那个ipv4的INADDR_ANY是主机字节序,而in6addr_any为网络字节序
2)socket建立
int socket(int domain, int type, int protocol);
差别在于ipv4时,第一个参数为AF_INET,而ipv6时,第一个参数为AF_INET6
sock_tcp = socket(AF_INET, SOCK_STREAM, 0)//ipv4
sock_tcp = socket(PF_INET6, SOCK_STREAM, 0)//ipv6
3)字符串地址和网络序ip地址的相互转换:
ipv4中字符串地址转换为网络序ip地址使用函数inet_aton,而ipv6使用inet_pton
int inet_aton(const char *cp, struct in_addr *inp);
int inet_pton(int af, const char *src, void *dst);
例:
inet_pton(AF_INET6, hostname, &snd_tcp_addr.sin6_addr)
其中hostname为c类型字符串ip地址
相反的转换ipv4使用inet_ntoa,而ipv6使用inet_ntop
char *inet_ntoa(struct in_addr in);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
例:
inet_ntop(PF_INET6,&rcv_udp_addr.sin6_addr,ip,sizeof(ip));
其中ip为c风格字符串
4)主机名和地址的转换
ipv4使用gethostbyname和gethostbyaddr
而通用采用的是getaddrinfo和getnameinfo
例:
getaddrinfo(ipaddr, port,&hints,&res);
使用ipv6需要包含:
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
一个例子
char IPdotdec[20]; //存放点分十进制IP地址
struct in_addr s; // IPv4地址结构体
int main (void)
{
// 输入IP地址
printf("Please input IP address: ");
scanf("%s", &IPdotdec);
// 转换
inet_pton(AF_INET, IPdotdec, (void *)&s);
printf("inet_pton: 0x%x/n", s.s_addr); // 注意得到的字节序
// 反转换
inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
printf("inet_ntop: %s/n", IPdotdec);
}