您的位置:首页 > 其它

初识IPv6(四)

2007-07-27 12:47 190 查看
4 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。
2 地址表示
  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_flowinfo和sin6_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()



[b]6、不受支持的API
XP和SERVER2003系列的IPV6协议不支持的API包括:

ninet_ntoa(),
ninet_addr(),
nhtonl(),
ngethostbyname(),
ngethostbyaddr(),

n

7、微软提供了一个代码升级检测工具Checkv4.exe,在最新的SDK中,首先把SDK加入环境变量中,然后在命令行模式下切换到当前代码所在的位子,输入:
checkv4 "要检测的代码文件名"
就会显示那些需要改变的代码的地方.

有一系列的名称/接口索引转换不被支持,但可能以后支持。
更多信息请参考:RFC2553,RFC2292[/b]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
);


n
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: