IP多播及编程_第1页
IP多播及编程_第2页
IP多播及编程_第3页
IP多播及编程_第4页
IP多播及编程_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、IP多播(也称多址广播或组播)技术,是一种允许一台或多台主机(多播源)发送单一数据 包到多台主机(一次的,同时的)的TCP/IP网络技术。多播作为一点对多点的通信,是节 省网络带宽的有效方法之一。在网络音频/视频广播的应用中,当需要将一个节点的信号传 送到多个节点时,无论是采用重复点对点通信方式,还是采用广播方式,都会严重浪费网 络带宽,只有多播才是最好的选择。多播能使一个或多个多播源只把数据包发送给特定的多 播组,而只有加入该多播组的主机才能接收到数据包。目前,IP多播技术被广泛应用在网 络音频/视频广播、AOD/VOD、网络视频会议、多媒体远程教育、“pus!技术(如股票行情 等) 和虚拟

2、现实游戏等方面。一、IP多播技术简介IP多播地址和多播组IP多播通信必须依赖于IP多播地址,在IPv4中它是一个D类IP地址,范围从 到55,并被划分为局部 链接多播地址、预留多播地址和管理权限多播地址三 类。其中,局部链接多播地址范围在55,这是为路由协议和其它用途保 留的地址,路由器并不转发属于此范围的IP包;预留多播地址为55, 可用于全球范围(如Internet)或网络协议;管理权限多播地址为55, 可供组织内部使用,类

3、似于私有IP地址,不能用于Internet,可限制多播范围。使用同一个IP多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。 一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数 目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。此外,不属于某一个 多播组的主机也可以向该多播组发送数据包。IP多播技术的硬件支持要实现IP多播通信,要求介于多播源和接收者之间的路由器、集线器、交换机以及主 机均需支持IP多播。目前,IP多播技术已得到硬件、软件厂商的广泛支持。(1)主机支持 IP 多播通信的平台包括 Windows CE 2.1、Windows 9

4、5、Windows 98、Windows NT 4 和Windows 2000等,运行这些操作系统的主机都可以进行IP多播通信。此外,新生产的网 卡也几乎都提供了对IP多播的支持。(2)集线器和交换机目前大多数集线器、交换机只是简单地把多播数据当成广播来发送接收,但一些中、 高档交换机提供了对IP多播的支持。例如,在3COM SuperStack 3 Swith 3300交换机上可启 用802.1p或IGMP多播过滤功能,只为已侦测到IGMP数据包的端口转发多播数据包。(3)路由器多播通信要求多播源节点和目的节点之间的所有路由器必须提供对Internet组管理协议(IGMP)、多播路由协议(如

5、PIM、DVMRP等)的支持。当一台主机欲加入某个多播组时,会发出主机成员报告”的IGMP消息通知多播路由 器。当多播路由器接收到发给那个多播组的数据时,便会将其转发给所有的多播主机。多 播路由器还会周期性地发出主机成员查询”的IGMP消息,向子网查询多播主机,若发现某 个多播组已没有任何成员,则停止转发该多播组的数据。此外,当支持IGMP v2的主机(如 Windows 98/2000计算机)退出某个多播组时,还会向路由器发送一条“离开组”的IGMP消 息,以通知路由器停止转发该多播组的数据。但只有当子网上所有主机都退出某个多播组 时,路由器才会停止向该子网转发该多播组的数据。使用多播路由协

6、议,路由器可建立起从多播源节点到所有目的节点的多播路由表,从 而实现在子网间转发多播数据包。例如,PIM (协议独立多播)就是一种多播路由协议,它 有两种类型:稀疏模式(sparse- mode)和密集模式(dense-mode)。以Cisco 2621路由器为 例,启用IP多播转发功能的基本设置如下:c2621(config)# ip multicast-routing启动IP多播,使路由器成为一个多播路由器c2621(config)# int f0/0配置快速以太网端口 0c2621(config-if)# ip pim dense-mode (或 sparse-mode)启动 PIM,同

7、时激活 IGMP 协议c2621(config-if)# int f0/1 配置快速以太网端口1c2621(config-if)# ip pim dense-mode (或 sparse-mode)二、IP多播应用的编程方法在实际应用中,编程人员通常需要自己编制底层网络应用程序来实现网上的底层通信, 如具体实现IP多播通信的功能。编制底层网络应用程序通常要借助于网络数据通信编程接 口,而在不同的操作系统中所提供的网络编程接口是有所不同的,如在Microsoft Windows 环境下的网络编程接口就是Windows套接字(Windows Socket,简称Winsock)。Winsock提供了

8、包括TCP/IP、IPX等多种通信协议下的编程接口。不同的Windows版本 支持不同的Winsock版本,其中Windows 95等早期版本本身只支持Winsock1.1 (16位)下 的编程(可以通过安装相关的软件包使其支持Winsock2.0),而Windows98、Windows NT4.0、 Windows 2000 则直接支持 Winsock2.0 (32 位)。Winsock2.0 是 Winsock1.1 的扩展,除兼容 Winsock1.1 API夕卜,还定义了一套可支持IP多播的与协议无关的API。使用Winsock 2.0实现IP多播的一般步骤如下:1.初始化Winsoc

9、k资源在使用 Winsock之前,必须调用WSAStartup()函数初始化 Windows Sockets DLL。它允许 应用程序或DLL指定Windows Sockets API要求的版本。2.创建套接字调用WSASocket()函数可以创建一个使用UDP协议的套接字,它是加入多播组的初始 化套接字,并且以后数据的发送和接收都在该套接字上进行。针对IP多播通信,可将参数 dwFlags 设置为 WSA_FLAG_MULTIPOINT_C_LEAF、 WSA_FLAG_MULTIPOINT_D_LEAF 和 WSA_FLAG_OVERLAPPED的位和,指明IP多播通信在控制层面和数据层面

10、都是“无根的”, 只存在叶节点,它们可以任意加入一个多播组,而且从一个叶节点发送的数据会传送到每一 个叶节点(包括它自己);创建的套接字具有重叠属性。设置套接字的选项调用setsockopt(函数为套接字设置SO_REUSEADDR选项,以允许套接字绑扎到一个已 在使用的地址上。绑定套接字调用bind()函数绑定套接字,从而将创建好的套接字与本地地址和本地端口联系起来。 对于多播通信来说,发送和接收数据通常采用同一个端口。设置多播套接字的模式WSAIoctl()函数的命令码SIO_MULTICAST_LOOP用来允许或禁止多播通信时发送出去的 通信流量是否也能够在同一个套接字上被接收(即多播返

11、回)。值得注意的是,在Windows 95/98/NT 4中,默认是允许多播返回,但不能设置禁止,否则会出错;只有在Windows 2000 以上版本中,才能设置允许/禁止多播返回。WSAIoctl()函数的命令码SIO_MULTICAST_SCOPE用来设置多播传播的范围,即生存时间 TTL。每当多播路由器转发多播数据包时,数据包中的TTL值都会被减1,若数据包的TTL 减少到0,则路由器将抛弃该数据包。TTL的值是多少,多播数据便最多能经过多少个多播 路由器。例如,TTL值为0,则多播只能在本地主机 的多个套接字间传播,而不能传播到网 线”上;TTL值为1 (默认值),则多播数据遇到第一个

12、路由器,便会被它无情”地丢弃,不 允许传出本地网络之外,即只有同一个网络内的多播组成员才能收到多播数据。加入一个多播组调用WSAJoinLeaf()函数可加入一个多播组并指定角色(发送者/接收者)。 调用时,参数dwFlags可指定套接字作为发送者(JL_SENDER_ONLY)、接收者 (JL_RECEIVER_ONLY)或身兼两者(JL_BOTH)。调 用成功后会返回一个多播套 接字,调用closesocket()函数关闭该套接字就离开了多播组,此时可以调用 WSAJoinLeaf()函数再次加入多 播组。注意,对多播组数据的接收和发送不能在 该套接字上完成。向多播组发送数据调用sendt

13、o()函数,可在指定的UDP套接字上向指定的多播组发送多播数 据。调用时,参数to应指向多播组的IP地址。值得注意的是,若一个应用程序 只是打算给多播组发送数据,便不必加入一个多播组。8 .等待事件调用WSAAsyncSelect ()函数,使套接字置于非阻塞模式,这时应用程序就 可在该套接字上接收以Windows消息为基础的网络事件通知。例如,若参数 lEvent值为FD_READ,则应用程序可在套接字上接收到“数据正等待被读入”的 通知。从多播组接收数据调用recvfrom函数,可在指定的UDP套接字上读取输入数据。多播通信中 数据的发送与接收一般采用同一个端口,因此其发送套接字和接收套接

14、字是一样 的。关闭套接字,释放Winsock资源。在多播通信结束后,先调用closesocket()函数关闭多播套接字和UDP套接 字,然后调用WSACleanup ()函数结束对Windows Sockets DLL的使用。三、应用实例为了说明IP多播技术的应用方法,本人在Visual C+.NET环境下设计了一 个简单的基于Windows Socket 2的IP多播应用程序,通过该例子读者可以掌握 IP多播应用程序设计的一般方法。该程序的具体设计方法如下:在Visual Studio.NET中建立一个基于对话框的MFC项目 CMulticastSocket。注意在“高级功能”设置中不要选择

15、“Windows套接字”, 这是因为MFC只支持Windows Socket 1而不支持Windows Socket 2。为了能使 用Winsock 2 API编程,在程序中应包含“winsock2.h”头文件,并在项目中加 入ws2_32.lib的静态库,该静态库应设置在项目属性的“链接器” “输 入” “附加依赖项”中。在对话框(类名CCMulticastSocketDlg)资源中,设置它的Caption为 “WinSock 2多播应用程序”,并添加以下控件:静态文本:Caption为“接收到的信息:”;编辑框:ID 为 IDC_RECEIVE_EDIT,Read Only、Auto Vs

16、croll、Vertical Scroll 和Multiline属性值都为True静态文本:Caption为“发送的信息:”编辑框:ID 为 IDC_SEND_EDIT第一个按钮:Caption为“加入多播组(&J)”,ID为IDC_JOIN_BUTTON 第二个按钮:Caption 为“多播发送(&S)”,ID 为 IDC_SEND_BUTTON 第三个按钮:Caption为“离开多播组(&L)”,ID为IDC_LEAVE_BUTTON第四个按钮:Caption 为“退出(&Q)”,ID 为 IDC_QUIT_BUTTON为两个编辑框分别添加相关联的CString类型的变量m_SendMes

17、sage和 m_ReceiveMessage;为四个按钮添加相应的消息处理函数;为对话框添加定时器 消息(用于定时显示接收到的消息)及其消息处理函数。添加一个新的对话框资源,设置它的Caption为“加入多播组”,保留 默认的两个按钮控件,同时添加添加以下控件:静态文本:Caption为“IP多播组地址:”编辑框:ID 为 IDC_IPADDRESS_EDIT静态文本:Caption为“IP多播端口:”编辑框:ID 为 IDC_PORT_EDIT静态文本:Caption为“生存时间:”编辑框:ID 为 IDC_TTL_EDIT复选框:Caption 为“多播返回:”,ID 为 IDC_LOOP

18、BACK_CHECK,Left Text 属性值为True。为该对话框添加新的类CJoinGroupDlg,它的基类为CDialog,然后为该对 话框中的三个编辑框分别添加相关联的变量,即 CSting m_IPAddress、UINT m_nPort、UINT m_nTTL;为复选框 添加相关联的BOOL类型的变量m_Loopback。在 CMulticastSocketDlg.h 文件的前面添加 CJoinGroupDlg 的头文件: #include “JoinGroupDlg.h”,并在 CCMulticastSocketDlg 类中添加了一个 CJoinGroupDlg 类实例对象

19、m_JoinDlg。为了能在对话框中接收网络事件通知,应增加一个用户自定义的消息及 消息处理函数,具体实现方法如下:在CMulticastSocketDlg.h文件的前面自 定义消息:#define WM_SOCK_MSG(WM_USER+166),并在 afx_msg 块中说明消息处 理函数:afx_msg LRESULT OnSocketMsg (WPARAM wParam,LPARAM lParam);在 CMulticastSocketDlg.cpp文件中的消息映射块中,使用ON_MESSAGE (WM_SOCK_MSG,OnSocketMsg )宏指令将消息映射到消息处理函数中,并具

20、体实现 消息处理函数:LRESULT CCMulticastSocketDlg: OnSocketMsg(WPARAM wParam,LPARAM lParam)。该程序的主要代码可参见程序清单,相关函数的详细说明可参看Microsoft MSDN 帮助系统。为了节省篇幅,程序中省略了部分自动生成的和用于错误处理的代码。程序清单: / CMulticastSocketDlg.cpp :实现文件#include stdafx.h”#include winsock2.h#include CMulticastSocket.h”#include CMulticastSocketDlg.h”DWORD

21、cbRet;SOCKET Sock,SockM; HYPERLINK file:/UDP file:/UDP 套接字,多播套接字BOOL bFlag,bJoin;SOCKADDR_IN local,Remote,From; file:/分别指向本地、多播组和数据来源的IP地址与端口int Fromlen;char ReceiveBuf32000; file:/接收缓冲区BOOL bDataReceived;BEGIN_MESSAGE_MAP(CCMulticastSocketDlg, CDialog)ON_BN_CLICKED(IDC_JOIN_BUTTON, OnBnClickedJoinB

22、utton)ON_BN_CLICKED(IDC_LEAVE_BUTTON, OnBnClickedLeaveButton)ON_BN_CLICKED(IDC_QUIT_BUTTON, OnBnClickedQuitButton)ON_BN_CLICKED(IDC_SEND_BUTTON, OnBnClickedSendButton)ON_WM_TIMER()ON_MESSAGE(WM_SOCK_MSG,OnSocketMsg)END_MESSAGE_MAP()BOOL CCMulticastSocketDlg:OnInitDialog()(CDialog:OnInitDialog();SetT

23、imer(1,100,NULL); file:/设置定时器Fromlen=sizeof(From);bDataReceived二TRUE;bJoin=FALSE;return TRUE; /除非设置了控件的焦点,否则返回TRUE void CCMulticastSocketDlg:OnBnClickedJoinButton() file:/加入多播组 (if(m_JoinDlg.DoModal()=IDOK)(WORD wVersionRequested;WSADATA wsaData;int北京中庆;wVersionRequested = MAKEWORD(2,2);北京中庆=WSAStar

24、tup(wVersionRequested, &wsaData); file:/初始化WinSock2 资源if(北京中庆!二0)(AfxMessageBox(不能加载Windows套接字动态链接库,MB_OK);return;if (LOBYTE(wsaData.wVersion) !=2 | HIBYTE(wsaData.wVersion) !=2)(AfxMessageBox(WinSock DLL 不支持 2.0 版本,MB_OK);WSACleanup();return;file:/创建一个套接字Sock二WSASocket(AF_INET,SOCK_DGRAM,IPPROTO_UD

25、P,(LPWSAPROTOCOL_INFO)NULL,0,WSA_FLAG_OVERLAPPED| WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF);bFlag=TRUE; file:/设置套接字选项,使套接字为可重用端口地址 setsockopt(Sock,SOL_SOCKET,SO_REUSEADDR,(char*)&bFlag,sizeof(bFlag);file:/将套接字绑定到用户指定端口及默认的接口memset(&local,0,sizeof(local);local.sin_family=AF_INET;local.si

26、n_port=htons(USHORT)m_JoinDlg.m_nPort);local.sin_addr.s_addr=htonl(INADDR_ANY);bind(Sock,(struct sockaddr FAR *)&local,sizeof(local);file:/设置多播数据报传播范围(生存时间TTL)WSAIoctl(Sock,SIO_MULTICAST_SCOPE,&m_JoinDlg.m_nTTL,sizeof(int),NULL,0,&cbRet,NULL,NULL);file:/设置多播返回(LOOKBACK)BOOL nLoopBack=m_JoinDlg.m_Loo

27、pback;WSAIoctl(Sock,SIO_MULTIPOINT_LOOPBACK,&nLoopBack,sizeof(nLoopBack),NULL,0,&cbRet,NULL,NULL);memset(&Remote,0,sizeof(Remote);Remote.sin_family=AF_INET;Remote.sin_addr.s_addr=inet_addr(m_JoinDlg.m_IPAddress);Remote.sin_port=htons(m_JoinDlg.m_nPort);file:/加入到指定的多播组,并指定为既作为发送者又作为接收者(JL_BOTH)SockM二WSAJoinLeaf(Sock,(sockaddr*)&Remote,sizeof(Remote),NULL,NULL,NULL,NULL,JL_BOTH);WSAAsyncSelect(Sock,m_hWnd,WM_SOCK_MSG,FD_READ); file:/注册网络消息 及其网络事件bJoin=TRUE; void CCMulticastSocketDlg:OnBnClickedSendButton() file:/多播发送(if(bJoin)(UpdateData(TRUE);const

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论