实例解析IPv6环境下的网络编程
2010-07-06 20:43:51 来源:WEB开发网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 <winsock2.h>
#include <ws2tcpip.h>
#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;
}
}
(全文完)
本文配套源码
更多精彩
赞助商链接