您当前的位置:五五电子网电子知识单片机-工控设备源码-程序基于C++中的IPv6网络程序设计分析 正文
基于C++中的IPv6网络程序设计分析

基于C++中的IPv6网络程序设计分析

点击数:7168 次   录入时间:03-04 12:02:19   整理:http://www.55dianzi.com   源码-程序

    IPv4 最初是由美国国防部开发的用于网际互联(IP)协议,后来它不仅发展了TCP,而且还进一步发展了IPv4(IP 协议4.0版)。IPv4现在已经广泛应用于Internet网络中,同时也应用于大多数计算机系统,局域网和广域网中。然而,随着Internet 中的计算机数量突飞猛涨,IPv4 的局限性越发明显:

    1.IPv4地址数目面临耗尽,日近紧张;

    2.IPv4寻址并非完全分等级,这使得Internet 枢纽路由器必须维持大量的路由表,负担过重。

    3.IPv4的地址必须被静态分配或通过配置协议(如:DHCP)进行分配。IPv6的开发目标之一就是将提供更为简便的配置方案。

    于是IPv6(6.0版本)应运而生。在Window系统中,Windows XP 提供了IPv6的developer-release版本;Windows 2000也可在http://www.mICroSOFt.com/ipv6 下载 IPv6协议预览。

    一.IPv4地址及其寻址

    1.IPv4地址

    IPv4地址(常称IP地址)用一个32位数表示;通常表示位十进制格式,地址的每8位字节被表示转为一个十进制的数值,并由句点分隔,如:192.168.0.1;IPv4地址 通常分为A、B、C、D、E 五类。

    2.IPv4寻址

    在WiNSock 中,通过SOCKADDR_IN 结构来指定IPv4的地址和服务断口信息:

    STruct sockaddr_in {

    short sin_family ;//必须为AF_INET,表示使用IPv4地址簇

    u_short sin_Port; //TCP/UDP 端口

    struct in_addr sin_addr;// IP地址(以网络字节顺序排列, 4个字节)

    char sin_zero[8];//填充项

    }

    二.IPv6地址及其寻址

    1.IPv6地址

    IPv6地址与IPv4地址的显著的不同是128位,长度是IPv4地址的4倍。IPv6地址由16位字节分段表示,显示为冒号分隔的十六进制:

    21DA:00D3:0000:2F3A:B234:ED12:9C5A:DAC3

    IPv6地址的分配

    分配

    地址前缀

    保留地址0000 0000

    为NSAP预留0000 0001

    可聚合的全球单播地址001

    链接-本地单播地址1111 1110 10

    站点-本地单播地址1111 1110 11

    多播地址1111 1111

    2. IPv6的寻址

    Winsock中,寻址使用一下结构:

    struct sockaddr_in6{

    short sin6_family;// 地址簇:AF_INET6

    u_short sin6_port;//端口号

    u_lONg sin6_flowinfo;//连接标记通信量

    struct in6_addr sin6_addr;//16字节结构的IPv6 地址

    u_long sin6_scope_id;//地址所有的接口索引

    }

   



www.55dianzi.com

    三.独立于协议的地址及名称解析

    由此可见在寻址时,IPv4使用16字节的SOCK_ADDR_IN 结构,IPv6则使用28 字节的SOCK_ADDR_IN6 结构。为了解决这个问题,IPv6中引入了新的寻址函数。 [Page]

    1.getaddrinfo(),它提供独立于协议的名称解析:

    int getaddrinfo(

    const char *FAR *nodenAME,

    const char FAR* SERvname,

    const struct addrinfo FAR *hins,

    struct addrinfo FAR *FAR *res

    );

    l 第一参数:nodename,以空字节结束的主机名或文字地址

    l 第二参数:servname,包含端口或服务名(如:FTP,TELNET)的以空字节结束的字符串

    l 第三个参数:hins 是一个结构(addrinfo),包含名称解析的执行方式选项

    l 第四个参数:res ,用于返回 addrinfo 结构的一个或多个链表

    结构addrinfo 的定义:

    struct addrinfo{

    int ai_flags;

    int ai_family;

    int ai_socktype;

    int ai_protocol;

    size_t ai_addrlen;

    char *ai_CANnoname;

    struct sockaddr *ai_addr;

    struct addrinfo *ai_next;

    }

    l ai_flags 选值:AI_PASSIVE:可以用来获取能够传递给bind函数的地址,此时nodename应设置为NULL,servname为欲绑定的端口;AI _CANONNAME 表示nodename 是主机名;AI_NUMBERICHOST 表示, nodename 是一个文字字符串地址(如:“192.168.0.1”)

    l ai_family 选值:AI_INET或PF_INET(IPv4地址簇);AI_INET6或PF_INET6(IPv6地址簇);AI_UNSPEC(未指定,可能是IPv4或IPv6 地址簇)

    l ai_socktype选值:SOCK_DGRAM(UDP类型套接字);SOCK_STREAM (TCP类 型套接字)

    l ai_protocol 选值:IPPROTO_TCP (TCP/IP协议)

    如果函数解析成功,解析后的地址将通过res返回。如果名称被解析为多个地址,则返回一个由ai_next 字段形成的链表。每个由名称解析的地址在ai_addr中表示,长度在ai_addrlen中表示。

    2.getnameinfo()函数与getaddrinfo()相对应,功能相反。

    . int getnameinfo(

    const struct sockaddr FAR *sa,

    socklen_t salen, [Page]

    char FAR *host,

    DWORD hostlen,

    char FAR *serv,

    DWORD servlen,

    Int flags);

    以上参数的含义比较明显,不再一一说明。

    3.释放函数: freeaddrinfo(res);

    四、兼容IPv4和IPv6的网络程序设计

    兼容IPv4和IPv6的网络程序,显然涉及到两个部分:客户机和服务器。

    在Windows 网络编程中,Winsock是一种标准的API(应用程序接口),Winsock2版本已经发展成独立于协议的的接口,被广泛应用于Windows平台中。



www.55dianzi.com

    <一>客户机程序设计

    对于客户机来说,不管是建立TCP/UDP 连接,它都应知道服务器的主机名或IP 地址,同时将服务器地址解析为IPv4或IPv6地址都可以,一般可以考虑一下步骤:

    SOCKET s;

    struct addrinfo,hints,*res=NULL;

    char *szRemoteAddrESS;//主机名或IP 地址

    char *szRemotePort;//端口号

    int rc;

    1.用getaddrinfo() 函数解析地址。hins结构中 使用AF_UNSPEC标志,便可以获得地址簇类型(IPv4或IPv6)。

    MEMSet(&hintas,0,sizeof(hints));

    hints.ai_family=AF_UNSPEC;

    hints.ai_socktype=SOCK_STREAM;

    hints.ai_protocol=IPPROTO_TCP;

    rc=getaddrinfo(szRemoteAdddress,szRemotePort,&hints,&res);

    if(rc==WSANO_DATA)

    {// 无法解析,出错

    }

    用返回的addrinfo结构中的ai_family,ai_socketype,ai_protocol字段来创建套接字。

    s=Socket(res->ai_family,ai_socktype,res->protocol);

    if(s==INVALID_SOCKET)

    {//创建套接字失败

    }

    2.使用返回的addrinfo结构中的ai_addr来调用其他函数(connect(),send()等).。

    rc==connect(s,res->ai_addr,res->addrlen);

    if(rc==SOCKET_error)

    {//连接失败;

    }

    。。。//完成其他编程

    <二>服务器程序设计

    服务器程序设计,应考虑到IPv4和IPv6 都具有各自的堆栈;因此如果服务器希望能同时接受IPv4和IPv6的连接,就必须能同时创建IPv4和IPv6套接字;一般可以考虑一下步骤:

    SOCKET socklisten[2];//*Socket变量

    char *szPort=”8080”;//*端口

    struct addinfo hints,*res=NULL,*ptr=NULL;

    int rc,i=0;

    1. 调用getaddrinfo()函数,该结构包含AI_PASSIVE,AF_UNSPEC标志,以及所需的套接字类型、协议及所需的本地端口(用来*和接受数据等)。函数将返回的两个addrinfo结构,分别可用于IPv4和IPv6*地址: [Page]

    mEMSet(&hints,0,sizeof(hints));

    hints.ai_family=AF_UNSPEC;

    hints.ai_socktype=SOCK_STREAM;

[1] [2] [3]  下一页


本文关键字:程序设计  网络  源码-程序单片机-工控设备 - 源码-程序