分享
 
 
 

实例解析IPv6下的VC网络编程2

王朝vc·作者佚名  2006-05-27
窄屏简体版  字體: |||超大  

实例解析IPv6下的VC网络编程2

实例篇

IPv6程序相对于IPv4改动并不大。其中主要的改动就是地址结构与地址解析函数。在RFC中详细说明了socket api 为适应IPv6所做的改动。而且windows平台与Linux平台在实现上也几乎是一样的。只不过头文件与支持程度等有所不同罢了(具体请参见RFC 2553与RFC 2292)。如读者有兴趣的话可以找RFC来看看,在这里就不再详细说明,只讲最简单的原理与例子,同时例出各主要socket api,如何使用,可以参考MSDN或是Linux中的MAN。

地址表示

IPv4使用32bits的地址表示,并有sockaddr_in和in_addr等结构应用于API中,而IPv6 使用128 bits 地址,也定义了本身的地址结构sockaddr_in6和in6_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;

}

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];

}

IP V4/IP V6专用函数

IPv6 API中一部分沿用了IPv4 API, 也新增了一些IPv6专用API,为使得程序具有更大的通用性,尽量避免使用IPv4专用函数,这些函数如下:

IP V4专用 是对应的IP v4/v6通用函数 功能说明

inet_aton( ) inet_ntop( ) 字符串地址转为IP地址

inet_ntoa( ) inet_pton( ) IP地址转为字符串地址

gethostbyname( ) Getipnodebyname( ) 由名字获得IP地

gethostbyaddr( ) struct hostent *getipnodebyaddr( ) IP地址获得名字

getaddrinfo( ) 获得全部地址信息

getnameinfo( ) 获得全部名字信息

未发生变化的函数 功能说明

socket( ) 建立Socket

bind( ) Socket与地址绑定

send( ) 发送数据(TCP)

sendto( ) 发送数据(UDP)

receive( ) 接收数据(TCP)

recv( ) 接收数据(UDP)

accept( ) 接收连接

listen( ) 网络监听

如上表格所示,IP V4专用函数在IP V6环境下已经不能使用,他们一般有一个对应的IP V4/V6通用函数,但是在使用通用函数的时候需要一个协议类型参数(AF_INET/AF_INET6)。另外还增加了两个功能强大的函数getaddrinfo( )和getnameinfo( ),几乎可以完成所有的地址和名字转化的功能。

Windows平台IPv6程序一例

下面我将给出windows平台下的一个例子。

系统平台:windows 2000 professional SP3+tpipv6-001205-SP3-IE6+VC6

说明:在本程序中只采用一个SOCKET,用WSAAsyncSelect来完成收与发的处理,为了方便起见,采用UDP方式。同时只专注IPv6的写法,不考虑函IPv4/IPv6兼容。如何编写IP无关的程序,有机会再另行撰文。

注:由于windows2000只是提供了IPv6的技术预览版,所以在有些地方支持上并不好。比如win2k在recvfrom的实现上好像有点问题,而linux中同样的代码却没问题。两者在recv的实现上都很正常。所以如果要开发程序最好是在window xp或是linux上进行。

下面是程序中关键的几步:

1.头文件的引入

#include

#include

#include "tpipv6.h" // Form IPv6 Tech Preview.(可以从tpipv6-001205-SP3-IE6安装后所在目录里找到)

#pragma comment(lib,"ws2_32")//引入库函数。

2.建SOCKET UpdateData(TRUE);

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

//hints.ai_family=PF_UNSPEC;//这样可以由系统自己进行判断,这里我们直接指定是IPV6

hints.ai_family=AF_INET6;//指定用IPV6协议

hints.ai_socktype=SOCK_DGRAM;

hints.ai_protocol=IPPROTO_UDP;//用UDP

hints.ai_flags=AI_NUMERICHOST;//IP用数字表示

rc=getaddrinfo((LPCTSTR )m_send,"2000",&hints,&res);//解析地址

if(rc!=0)

{

AfxMessageBox("fail");

return;

}

s_send=socket(res->ai_family,res->ai_socktype,res->ai_protocol);//建socket

if(s_send==INVALID_SOCKET)

{

AfxMessageBox("建本机发socket失败");return ;}

else

{

AfxMessageBox("建本机发socket成功");

//绑定本地监听端口bind

if(bind (s_send,res->ai_addr,res->ai_addrlen)==SOCKET_ERROR)

AfxMessageBox("bind失败");

else

{AfxMessageBox("bind成功");GetDlgItem(IDOK)->EnableWindow (TRUE); }

}

if ( WSAAsyncSelect( s_send, m_hWnd, UM_PACKET, FD_READ ) == SOCKET_ERROR )//异步选择

{

MessageBox( "WSAAsyncSelect failed" );

closesocket( s_send );

return;

}

3.发送 memset(&hints,0,sizeof(hints));

hints.ai_family=AF_INET6;

hints.ai_socktype=SOCK_DGRAM;

hints.ai_protocol=IPPROTO_UDP;//这里也可以改为0,让系统自己选

hints.ai_flags=AI_NUMERICHOST;

rc=getaddrinfo((LPCTSTR )m_receive,"2000",&hints,&res);//解析对方收地址

if(rc!=0)

{

AfxMessageBox("fail");

return;

}

rc=sendto(s_send,m_sendtxt,m_sendtxt.GetLength(),0,

res->ai_addr,res->ai_addrlen);

if (rc== SOCKET_ERROR)

{

AfxMessageBox("发送失败");

closesocket(s_send);

}

else

{

AfxMessageBox("发送成功");

}

4.异步触发事件 LRESULT CMy6dDlg::OnPacket( WPARAM wParam, LPARAM lParam )

{

char sBuf[128];

sockaddr_in6 sa;

int iAddrLen=sizeof( sa );

int a=sizeof(sockaddr);

ZeroMemory( &sa, sizeof( sa ) );

memset(&sBuf,0,sizeof(sBuf));

int iLen = recv(s_send, sBuf, sizeof(sBuf),0);//for win2k use recv

if(iLen<0)

{

fprintf(stderr,"recvfrom failed with error %d: %s\n",)WSAGetLastError(), DecodeError(WSAGetLastError()));

return 0;

}

else

{

sBuf[iLen] = 0;

CString sText;

char lpszAddressString[1000];

DWORD dwAddressStringLength=1000;

rc=WSAAddressToString((sockaddr*)&sa,sizeof(sa),NULL,

lpszAddressString,&dwAddressStringLength );

sText.Format( "recved [%s]", sBuf);//,sa.sin6_family==AF_INET6,

lpszAddressString);//for win2k

m_reclist.AddString( sText );

return 0;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有