基于IPv6的Winsock网络编程 点击:488 | 回复:0



sinap_zhj

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:12帖 | 1回
  • 年度积分:0
  • 历史总积分:184
  • 注册:2014年7月31日
发表于:2014-11-12 19:26:28
楼主

现有Internet的基础是IPv4,随着Internet的迅猛发展,IPv4的局限性越来越明显。传统的IPv4协议已经难以支持互联网的进一步扩张和新业务的特性,如:IP地址资源即将枯竭、路由表越来越大、缺乏服务质量保证和地址分配不便等。IETF的IPng工作组在1994年9月提出了一个正式的草案“The Recommendation for the IP Next Generation Protocol”,1995年底确定了IPng的协议规范,并称为“IP版本6”,即IPv6。
IPv6概述
IPv6指的是网络协议版本6,它是Internet协议的下一版本。IPv6不仅用来解决地址空间问题,而且还是满足市场的需要,交互多媒体应用、宽带应用、企业之间的高速互连等新型应用。IPv6解决了IP地址枯竭、互联网骨干路由过于复杂、IP协议功能较少、IP协议没有考虑到安全性、路由计算比较复杂等问题。
IPv6协议使用了128位数据来表示网络地址,而原有的IPv4仅仅能使用32位地址,128位长的地址能够为各种各样可能的设备分配一个地址,彻底解决地址紧张问题。
IPv6协议在数据包中使用对齐的头部格式,而不是变长的头部,就简化了路由处理,并且IPv6的路由结构更为简单,使得网络骨干路由可以更简单和高效,满足互联网越来越普及的需要。
IPv6提供更方便的自动配置能力,特别是对移动IP支持,这对于移动设备的网络连接及漫游是非常重要的。
IPv6协议中包括了很多新的安全特性,如IPSec等,这些都是互联网安全通信所必须的。
IPv6中还提供了分组优先级的定义,以解决对多媒体通信等要求实时或准实时的通信需求,提供网络传输的服务质量(Qos)。
IPv6还提供对组播的支持,以便使用有限的带宽对多点通信进行支持,充分解决网络资源,这对大部分多媒体应用是非常必要的。
IPv6网络编程
IPv6下的网络编程相对于IPv4主要是地址结构与地址解析函数的改动。IPv4使用32bits的地址表示,并有sockaddr_in和in_addr等结构应用于API中,而IPv6 使用128 bits 地址,也定义了本身的地址结构sockaddr_in6和in6_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];
}
程序源代码
UDP协议(User Datagram Protocol),即用户数据报协议,是定义用来在互连网络环境中提供包交换的计算机通信的协议。UDP网络编程步骤如下:加载Windows Sockets DLL、创建套接字、绑定端口、注册网络事件、发送和接收数据、最后关闭套接字。
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32")
// 加载Windows Sockets DLL
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
// 创建套接字
ADDRINFO Hints;
ADDRINFO *AddrInfo;
SOCKET Socket;
memset(&Hints, 0, sizeof(Hints));
Hints.ai_family = AF_UNSPEC;
Hints.ai_socktype = SOCK_DGRAM;
Hints.ai_protocol = IPPROTO_IP;
Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
getaddrinfo(NULL, 2005, &Hints, &AddrInfo);
if (AddrInfo->ai_family == AF_INET)
        AfxMessageBox("当前协议族为IPv4");
else if (AddrInfo->ai_family == AF_INET6)
        AfxMessageBox("当前协议族为IPv6");
Socket = socket(AddrInfo->ai_family, AddrInfo->ai_socktype, AddrInfo->ai_protocol);
// 绑定端口
bind(Socket, AddrInfo->ai_addr, (int) AddrInfo->ai_addrlen);
// 注册网络事件
#define WM_NETWORK_EVENT WM_USER + 101
WSAAsyncSelect(Socket, m_hWnd, WM_NETWORK_EVENT, FD_READ);
// 发送数据
ADDRINFO ToHints;
ADDRINFO *ToAddrInfo;
ToHints.ai_family = AF_UNSPEC;
ToHints.ai_socktype = SOCK_DGRAM;
ToHints.ai_protocol = IPPROTO_IP;
ToHints.ai_flags = AI_NUMERICHOST;
getaddrinfo("fe80::5efe:90.0.8.112", 2005, &ToHints, &ToAddrInfo);
char buf[] = "Hello IPv6";
int len = strlen(buf);
sendto(Socket, buf, len, 0, ToAddrInfo->ai_addr, (int) ToAddrInfo->ai_addrlen);
// 接收数据
afx_msg LRESULT OnNetworkEvent(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(WM_NETWORK_EVENT, OnNetworkEvent)
LRESULT CIPv6TestView::OnNetworkEvent(WPARAM wParam, LPARAM lParam)
{
    switch (WSAGETSELECTEVENT(lParam))
    {
    case FD_READ:
                char buf[1024];
                int nBytesRead = recv(Socket, buf, sizeof(buf), 0);
                if (nBytesRead != SOCKET_ERROR)
                {
                        buf[nBytesRead] = '\0';
                        AfxMessageBox(buf);
                }
        break;
        }
        return 0L;
}
// 关闭套接字
closesocket(Socket);
WSACleanup();
在上面的代码中,将协议族ai_family设置为AF_UNSPEC,其目的为了兼容IPv4,也可以直接设置为AF_INET6,表示使用IPv6;将协议ai_protocol设置为IPPROTO_IP,使其根据套接字类型ai_socktype自动选择协议,也可以直接设置为IPPROTO_UDP,表示使用UDP协议;AI_PASSIVE标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构;AI_NUMERICHOST标志置位时,表示调用中的节点名必须是一个数字地址字符串。

随着因特网及其应用在全球范围内的迅猛发展,以及无线和移动通讯技术在应用领域的广泛拓展,基于IPv4协议的网络技术面临着一系列的新问题,其中包括地址空间耗尽、缺少安全保障、服务质量难以保证以及移动性支持有限等。IPv6作为下一代互联网协议,深受世界各国的重视。发展IPv6不仅在国家战略的高度上具有重要意义,而且IPv6的市场空间十分巨大,IPv6的产业正显示出空前的活力。



热门招聘
相关主题

官方公众号

智造工程师