Socket Programming下IPv6的支持

来源:互联网 发布:笔试算法题 编辑:程序博客网 时间:2024/05/17 03:18

在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);
   
}

原创粉丝点击