ipv6 编码

     IPv6程序相对于IPv4改动并不大。其中主要的改动就是地址结构与地址解析函数。在RFC中详细说明了socket api 为适应IPv6所做的改动。而且windows平台与Linux平台在实现上也几乎是一样的。只不过头文件与支持程度等有所不同罢了(具体请参见RFC 2553与RFC 2292)。如读者有兴趣的话可以找RFC来看看,在这里就不再详细说明,只讲最 简单的原理与例子,同时例出各主要socket api,如何使用,可以参考MSDN或是Linux中的MAN。
        
1   增加的常量 IPV6 的地址族名和协议族名常为: AF_INET6    PF_INET6
地址表示
   IPv4 使用 32bits 的地址表示,并有 sockaddr_in in_addr 等结构应用于 API 中,而 IPv6 使用 128 bits 地址,也定义了本身的地址结构 sockaddr_in6 in6_addr

  //ipv4 addr
struct sockaddr_in
{
u_char sin_len;
u_char sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr
{
u_int32_t s_addr;
}
//ipv6 addr
 
struct sockaddr_in6
  {
u_char sin6_len;
u_char sin6_family;
u_int16_t sin6_port;
u_int32_t sin6_flowinfo;
struct in6_addr sin6_addr;
u_int32_t sin6_scope_id;
}
struct in6_addr
{
u_int8_t __u6_addr8[16];
}
 
除了族、端口和地址信息,此结构中还包含sin6_flowinfosin6_scope_id数据成员。在数据成员sin6_flowinfo中将包含IPV6报头中的通信流类别字段和流标签字段。在XP SERVER2003系统中不支持sin6_flowinfo数据成员。在数据成员sin6_scope_id中包含了范围ID,它用于标识一系列的接口,这些接口与地址字段中的地址相对应
 
3、通配地址     为了在具体的实现方案中为使用IPV4的连接或数据报选择一个源地址,在bind()函数 调用中将常量INADDR_ANY用作地址。
     IPV6地址类型(in6_addr)是一个结构变量,不能用常量为结构变量赋值,但常量可以 用于初始化这个结构,全球变量in6addr_any可以在赋值中使用,如
sin6.sin6_addr=in6addr_any;
或者常量IN6ADDR_ANY_INIT也可用于初始化地址结构(只在声明的时候),如
struct in6_addr anyaddr=IN6ADDR_ANY_INIT;
     在IPV4中的connect(),send()和sendmsg()函数调用中,使用常量INADDR_LOOPBACK来 和本地节点中的服务进行通信。对于IPV6的回环,全局变量(in6addr_loopback)在赋值中 使用,常量(IN6ADDR_LOOPBACK_INIT)用于在声
明时的初始化。注意,IPV4的INADDR_XXX常量以主机字节顺序定义,而IPV6的以网络字节顺序定义
 
4、核心套接字函数
    在核心套接字函数中所进行的地址传递实际上是传递一个不透明的地址指针和长度, 因此,IPV6的核心套接字函数不需要对原来的进行改变。我们只需要简单地提供适当的IPV6地址结构和族常量。
接受地址参数的套接字函数有:
bind()
connect()
send()
sendto()
返回地址的套接字函数有:
accept()
recvfrom()
recv()
getpeername()
getsockname()
 

6、不受支持的API     XP和SERVER2003系列的IPV6协议不支持的API包括:
n inet_ntoa(),
n inet_addr(),
n htonl(),
n gethostbyname(),
n gethostbyaddr(),
n
7、微软提供了一个代码升级检测工具Checkv4.exe,在最新的SDK中,首先把SDK加入环境变量中,然后在命令行模式下切换到当前代码所在的位子,输入:
checkv4 "要检测的代码文件名"
就会显示那些需要改变的代码的地方.

 
有一系列的名称/接口索引转换不被支持,但可能以后支持。
更多信息请参考:RFC2553,RFC2292 5、名称 / 地址的转换     在IPV4中,应用程序使用gethostbyname()函数来将主机名解析为一个或多个IP地址, 但它不允许调用者 指定所需地址类型的任何信息,因此IPV6中引入一个名字getaddrinfo( )的新API,此API与协议无关,此调用的返回值是addrinfo的结构指针,以后可用它来打开 和使用套接字,getaddrinfo()原型如下:

int getaddrinfo(
    IN const char FAR *nodename,
    IN const char FAR *servname,
    IN const struct addrinfo FAR *hints,
    OUT struct addrinfo
 FAR *FAR *res
    );

struct addrinfo {
    int     ai_flags;     /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
    int     ai_family;    /* PF_xxx */
    int     ai_socktype;  /* SOCK_xxx */
    int     ai_protocol;  /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
    size_t  ai_addrlen;   /* length of ai_addr */
    char   *ai_canonname; /* canonical name for nodename */
    struct sockaddr  *ai_addr; /* binary address */
    struct addrinfo  *ai_next; /* next structure in linked list */
  };

 
反向查找可以通过使用另一个新的套接字函数getnameinfo()来进行,为使用此API调用者需要提供一个套接字地址结构。getnameinfo()原型如下:

int getnameinfo(
    IN const struct sockaddr FAR *sa,
    IN socklen_t salen,
    OUT char FAR *host,
    IN size_t hostlen,
    OUT char FAR *serv,
    IN size_t servlen,
    IN int flags
    );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值