转眼10月份将至,今年的高校杯应该轮到我参加了吧..得准备一下先.开发课题已经选好
<< 多媒体远程教育>>,开发语言:C#  模式:C/S 基与WinForm.  其中涉及到一个技术就是多播.
      IP多播(也称多址广播或组播)技术,是一种允许一台或多台主机(多播源)发送单一数据包到多台主机(一次的,同时的)的TCP/IP网络技术。多播作为一点对多点的通信,是节省网络带宽的有效方法之一。在网络音频/视频广播的应用中,当需要将一个节点的信号传送到多个节点时,无论是采用重复点对点通信方式,还是采用广播方式,都会严重浪费网络带宽,只有多播才是最好的选择。多播能使一个或多个多播源只把数据包发送给特定的多播组,而只有加入该多播组的主机才能接收到数据包。目前,IP多播技术被广泛应用在网络音频/视频广播、AOD/VOD、网络视频会议、多媒体远程教育(我要做的就是这个软件 : D.....)、“push”技术(如股票行情等)和虚拟现实游戏等方面。

  一、IP多播技术简介

  1.IP多播地址和多播组
  IP多播通信必须依赖于IP多播地址,在IPv4中它是一个D类IP地址,范围从224.0.0.0到239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类。其中,局部链接多播地址范围在224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包;预留多播地址为224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议;管理权限多播地址为239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。

  使用同一个IP多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。此外,不属于某一个多播组的主机也可以向该多播组发送数据包。

  2.IP多播技术的硬件支持
  要实现IP多播通信,要求介于多播源和接收者之间的路由器、集线器、交换机以及主机均需支持IP多播。目前,IP多播技术已得到硬件、软件厂商的广泛支持。

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

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

  使用多播路由协议,路由器可建立起从多播源节点到所有目的节点的多播路由表,从而实现在子网间转发多播数据包。例如,PIM(协议独立多播)就是一种多播路由协议,它有两种类型:稀疏模式(sparse-mode)和密集模式(dense-mode)。以Cisco 2621路由器为例,启用IP多播转发功能的基本设置如下:

  c2621(config)# ip multicast-routing 启动IP多播,使路由器成为一个多播路由器
  c2621(config)# int f0/0 配置快速以太网端口0
  c2621(config-if)# ip pim dense-mode(或sparse-mode)启动PIM,同时激活IGMP协议
  c2621(config-if)# int f0/1 配置快速以太网端口1
  c2621(config-if)# ip pim dense-mode(或sparse-mode)

  二、IP多播应用的编程方法

  在实际应用中,编程人员通常需要自己编制底层网络应用程序来实现网上的底层通信,如具体实现IP多播通信的功能。编制底层网络应用程序通常要借助于网络数据通信编程接口,而在不同的操作系统中所提供的网络编程接口是有所不同的,如在Microsoft Windows环境下的网络编程接口就是Windows套接字(Windows Socket,简称Winsock)。
Winsock提供了包括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.初始化Winsock资源
  在使用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多播通信在控制层面和数据层面都是“无根的”,只存在叶节点,它们可以任意加入一个多播组,而且从一个叶节点发送的数据会传送到每一个叶节点(包括它自己);创建的套接字具有重叠属性。

  3.设置套接字的选项
  调用setsockopt()函数为套接字设置SO_REUSEADDR选项,以允许套接字绑扎到一个已在使用的地址上。

  4.绑定套接字
  调用bind()函数绑定套接字,从而将创建好的套接字与本地地址和本地端口联系起来。对于多播通信来说,发送和接收数据通常采用同一个端口。

  5.设置多播套接字的模式
  WSAIoctl()函数的命令码SIO_MULTICAST_LOOP用来允许或禁止多播通信时发送出去的通信流量是否也能够在同一个套接字上被接收(即多播返回)。值得注意的是,在Windows 95/98/NT 4中,默认是允许多播返回,但不能设置禁止,否则会出错;只有在Windows 2000以上版本中,才能设置允许/禁止多播返回。
  WSAIoctl()函数的命令码SIO_MULTICAST_SCOPE用来设置多播传播的范围,即生存时间TTL。每当多播路由器转发多播数据包时,数据包中的TTL值都会被减1,若数据包的TTL减少到0,则路由器将抛弃该数据包。TTL的值是多少,多播数据便最多能经过多少个多播路由器。例如,TTL值为0,则多播只能在本地主机的多个套接字间传播,而不能传播到“网线”上;TTL值为1(默认值),则多播数据遇到第一个路由器,便会被它“无情”地丢弃,不允许传出本地网络之外,即只有同一个网络内的多播组成员才能收到多播数据。

  6.加入一个多播组
  调用WSAJoinLeaf()函数可加入一个多播组并指定角色(发送者/接收者)。调用时,参数dwFlags可指定套接字作为发送者(JL_SENDER_ONLY)、接收者(JL_RECEIVER_ONLY)或身兼两者(JL_BOTH)。调用成功后会返回一个多播套接字,调用closesocket()函数关闭该套接字就离开了多播组,此时可以调用WSAJoinLeaf()函数再次加入多播组。注意,对多播组数据的接收和发送不能在该套接字上完成。

  7.向多播组发送数据
  调用sendto()函数,可在指定的UDP套接字上向指定的多播组发送多播数据。调用时,参数to应指向多播组的IP地址。值得注意的是,若一个应用程序只是打算给多播组发送数据,便不必加入一个多播组。

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

  10.关闭套接字,释放Winsock资源。
  在多播通信结束后,先调用closesocket()函数关闭多播套接字和UDP套接字,然后调用WSACleanup()函数结束对Windows Sockets DLL的使用。

  三、应用实例
下面得代码是多播代理类:)

  1using System;
  2using System.Net;
  3using System.Net.Sockets;
  4using System.Threading;
  5
  6namespace UDPReceiver
  7{
  8public delegate void OnReceiveEventHandler(string xmlPack);
  9
 10/**//// <summary>
 11/// MultiCast 的摘要说明。
 12/// </summary>
 13public class MultiCast
 14{
 15private string addr;
 16private int port;
 17private UdpClient subscriber;
 18private bool bShutDown = true;
 19private Thread thReceive;
 20
 21/**//// <summary>
 22/// 数据到达事件
 23/// </summary>
 24public event OnReceiveEventHandler OnReceive;
 25
 26/**//// <summary>
 27/// 构造
 28/// </summary>
 29/// <param name="multiCastIP">组播IP</param>
 30/// <param name="udpPort">端口</param>
 31public MultiCast(string multiCastIP,int udpPort)
 32{
 33addr = multiCastIP;
 34port = udpPort;
 35OnReceive += new OnReceiveEventHandler(MultiCast_OnReceive);
 36}
 37
 38/**//// <summary>
 39/// 启动监听
 40/// </summary>
 41public void Startup()
 42{  
 43if (!bShutDown)
 44return;
 45
 46subscriber = new UdpClient(port); 
 47IPAddress ipMultiCast = IPAddress.Parse(addr);
 48
 49try
 50{
 51subscriber.JoinMulticastGroup(ipMultiCast);
 52}
 53catch(Exception ex)
 54{
 55System.Windows.Forms.MessageBox.Show("无法加入到多播组[" + addr + "]\n\n" + ex.ToString());
 56return;
 57}
 58
 59//抛出监听线程
 60bShutDown = false;
 61thReceive = new Thread(new ThreadStart(Receive));
 62           thReceive.Start();  
 63}
 64
 65/**//// <summary>
 66/// 关闭监听
 67/// </summary>
 68public void ShutDown()
 69{
 70bShutDown = true;
 71thReceive.Join(500);
 72
 73try
 74{
 75thReceive.Abort();
 76}
 77catch
 78{
 79
 80}
 81
 82subscriber.Close();
 83subscriber = null;
 84}
 85
 86private void MultiCast_OnReceive(string xmlPack)
 87{
 88//do nothing
 89}
 90
 91
 92private void Receive()
 93{
 94byte[] bytes = null;
 95IPEndPoint ipFrom = null;
 96string xml = "";
 97
 98while(!bShutDown)
 99{
100bytes = subscriber.Receive(ref ipFrom);
101
102if (bytes != null)
103{
104if (bytes.Length > 0)
105{
106xml = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
107//激发事件
108OnReceive(xml);
109}
110                }               
111}
112}
113}
114}

服务器段:

 1public class RecvBC
 2{
 3  byte[] message = new byte[2048];
 4  Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
 5
 6  public RecvBC()
 7  {
 8    IPEndPoint ipep=new IPEndPoint(IPAddress.Any, 7758);
 9    s.Bind(ipep);
10    IPAddress ip=IPAddress.Parse("224.0.0.1");
11    s.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.AddMembership,
12    new MulticastOption(ip,IPAddress.Any));
13  }
14
15  public byte[] Recv()
16  {
17    s.Receive(message );
18    return message;
19  }
20
21  ~RecvBC()
22  {
23    s.Close();
24  }
25}
26
27
28public class SendBC
29{
30  public SendBC()
31  {}
32
33  public void Send(byte[] message)
34  {
35    Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);
36    IPAddress ip=IPAddress.Parse("224.0.0.1");
37    s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, 
38                       new MulticastOption(ip));
39    s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 5);
40    IPEndPoint ipep=new IPEndPoint(ip, 7758);
41    s.Connect(ipep);
42    s.Send(message,message.Length,SocketFlags.None);
43    s.Close();
44  }
45}
46
47

再给个实例

发送端:
 string k="来自【"+home_ip+"】&";


data=this.richTextBox1.Text.Trim();

string a=k+data+"<the end>";
byte []bytedata=System.Text.Encoding.Default.GetBytes(a);

//server的ip和port
ipadd=IPAddress.Parse("225.1.1.10");//多播IP地址
endpoint=new IPEndPoint(ipadd,9999);

/**/
try
{
sclient=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,System.Net.Sockets.ProtocolType.Udp);

socketdone.Reset();

sclient.BeginSendTo(bytedata,0,bytedata.Length,0,endpoint,new AsyncCallback(this.sendcallback),sclient);
socketdone.WaitOne();//阻塞线程

sclient.Shutdown(SocketShutdown.Both);
sclient.Close();

Application.DoEvents();
sclient=null;
this.button1.Enabled=true;


}
catch(Exception my)
{
 MessageBox.Show(my.Message.ToString(),"try(client)");
               socketdone.Reset();
return;

}
            
}




public void sendcallback(IAsyncResult ar)
{
try
{
Socket sclient=(Socket)ar.AsyncState;
int bytesend=sclient.EndSend(ar);

socketdone.Set();
}
catch(Exception my)
{
MessageBox.Show(my.Message.ToString(),"sendcallback(client)");
sclient.Shutdown(SocketShutdown.Both);
sclient.Close();
sclient=null;
}
}
接受端:
IPEndPoint localend1=new IPEndPoint(IPAddress.Any,9999);//本地终端
   //EndPoint my_endpoint=(EndPoint)localend1;


 


//create socket
slistener=new Socket(System.Net.Sockets.AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
        slistener.Bind(localend1);//UDP协议不支持端口尝试侦听操作



         IPAddress ipadd=IPAddress.Parse("225.1.1.10");//多播IP地址

         IPEndPoint endpoint=new IPEndPoint(IPAddress.Any,0);//定义远程终端
rem_endpoint=(EndPoint)endpoint;


//多播设置
MulticastOption option1=new MulticastOption(ipadd,IPAddress.Any);

//套接字设置
slistener.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP,SocketOptionName.AddMembership,option1);//IGMP协议是在IP模块中实现的
slistener.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP,SocketOptionName.MulticastTimeToLive,5);//IGMP协议是在IP模块中实现的,IP多路广播的生存时间



try
{
while(true)
{
socketevent.Reset();
 buffer=new byte[1024];
slistener.BeginReceiveFrom(buffer,0,buffer.Length,0, ref rem_endpoint,new AsyncCallback(ReceiveCallback),slistener);
   socketevent.WaitOne();
Application.DoEvents();

slistener.Close();
slistener=null;


}
}
catch(SocketException my)
{
MessageBox.Show(my.Message.ToString(),"error1(server)",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Hand);

}
public static ManualResetEvent socketevent=new ManualResetEvent(false);
public void ReceiveCallback(IAsyncResult ar)
{
try
{
Socket handler=(Socket)ar.AsyncState;
int bytesread=handler.EndReceiveFrom(ar,ref rem_endpoint);
//if there is some data
if(bytesread>0)
{
//append it to the main string
box=System.Text.Encoding.Default.GetString(buffer,0,buffer.Length);

box=box.Trim();

//see the file is over
if(box.IndexOf("<the end>")>0)
{
string []a=box.Split('&');
string b=a[1].Replace("<the end>","");

//委托更新UI线程
this.richTextBox1.Invoke(new UPDATE_richtext(this.update_richtext),new object[]{a[0],b});

this.richTextBox1.Invoke(new CHANG_color(this.chang_color),new object[]{this.richTextBox1.Text});
                      
socketevent.Set();
buffer=null;

handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
else
{
handler.BeginReceiveFrom(buffer,0,buffer.Length,0, ref rem_endpoint,new AsyncCallback(ReceiveCallback),handler);

}


}

}
catch(Exception my)
{
MessageBox.Show(my.Message.ToString());
}
在ReceiveCallback函数

if(bytesread>0)

这里设置断点

把Receive中

slistener.Close();
slistener=null;

去掉

专题完(有个问题就是音频传输)

转载于:https://www.cnblogs.com/ytml/archive/2005/08/10/211225.html

IP多播技术[为软件高校杯做准备]相关推荐

  1. 【miscellaneous】IP多播技术及其编程

    标  题: IP多播技术及其编程  发信站: 幽幽黄桷兰 (Mon Jun 16 10:35:39 2003)  转信站: SMTH!maily.cic.tsinghua.edu.cn!news2.u ...

  2. IP多播技术及其应用

    随着全球互联网(Internet)的迅猛发展,上网人数正以几何级数快速增长,以因特网技术为主导的数据通信在通信业务总量中的比列迅速上升,因特网业务已成为多媒体通信业中发展最为迅速.竞争最为激烈的领域. ...

  3. IP多播技术介绍(二)

    2.MOSPF(Multicast OSPF) 开放式组播最短路径优先(MOSPF)由FRC1584为OSPF组播的扩展,是OSPFV2单播路由协议的一个扩展. 组播扩展 OSPF(MOSPF)在原 ...

  4. 管理active directiory中的用户和计算机管理磁盘,IP多播桌面视频会议系统媒体流管理与安全机制的分析.pdf...

    摘要 摘 要 近年来,随着网络技术的发展和通信技术的进步,人与人的交流日趋频繁. 由此视频会议系统已成为研究的一个热点.本文介绍了利用cOM组件技术开发的 一套基于IP多播的讨论式桌面会议系统,并且介 ...

  5. 软件开发技术文档_你知道,直播软件开发需要做的准备工作有哪些?

    随着互联网技术的发展和智能手机的迅速普及,直播软件市场需求正在增长.那么直播平台的发展如何?在软件开发过程中应注意什么?直播软件开发需要做是准备工作有哪些? 1.直播软件开发方向: 一般而言,开发直播 ...

  6. 《TCP/IP路由技术(第二卷)》一1.2 EGP的操作

    本节书摘来自异步社区<TCP/IP路由技术(第二卷)>一书中的第1章,第1.2节,作者[美]Jeff Doyle,CCIE #1919 , Jennifer DeHaven Carroll ...

  7. 计算机网络(十九)其他IP相关技术

    计算机网络(十九)其他IP相关技术 1.IP多播相关技术 2.IP任播 3.通信质量控制 a.控制通信质量的机制 b.IntServ c.DiffServ 4.显式拥塞通知 5.Mobile IP a ...

  8. IP多播(计算机网络-网络层)

    目录 一对多通信的应用需求 单播 vs 多播 多播路由器(Multicast Router) IP 多播的一些特点 D 类 IP 地址与以太网多播地址的映射关系 IP多播需要两种协议 互联网组管理协议 ...

  9. 计算机网络 IP多播

    IP 多播的基本概念 IP 多播 (multicast,以前曾译为组播) 已成为互联网的一个热门课题. 目的:更好地支持一对多通信. 一对多通信:一个源点发送到许多个终点. 例如,实时信息的交付(如新 ...

最新文章

  1. Ubuntu中Atom安装与使用
  2. 2018 ACM博士论文奖公布:伯克利博士获奖,清华姚班马腾宇荣誉提名(附论文链接)...
  3. Amazon Aurora 升级, 兼容 PostgreSQL
  4. mysql设置slave复制_mysql5.5建立主从复制(setupmaster-slavereplication)_MySQL
  5. 前端学习(3309):redux项目创建和概况
  6. 【Java】文件操作
  7. Vue 使用 v-show 失效
  8. webview的javascript与Native code交互
  9. zmap扫描mysql_网站安全扫描工具 zmap怎么进行全网检测 - 驱动管家
  10. Alex 的 Hadoop 菜鸟教程: 第14课 Sqoop1 从Hbase导出mysql
  11. mysql去空格trim_mysql去空格函数trim
  12. “磁碟机”病毒技术分析报告
  13. 微信支付异常故障记录
  14. BZOJ 3772: 精神污染
  15. 大数据技术架构_独家解读!阿里首次披露自研飞天大数据平台技术架构
  16. Windos 下python2.7安装 pymssql 解决方案
  17. PARSEC使用与下载
  18. 徽章机器人gba_《真型机器人》GBA简单攻略
  19. PS如何便捷的使用仿制图章和画笔工具
  20. DLink_RCE_CVE-2019-17621浅析

热门文章

  1. 计算机病案管理系统,TWQ病案管理软件
  2. 高中信息技术——GoldWave音频处理刷题点整理
  3. Excel——字符串操作函数
  4. “21天好习惯”第一期-15
  5. 什么是服务的熔断降级
  6. Linux man C++ 库函数
  7. App跳转到权限设置界面
  8. CentOS 6 安装最新的 Redis 2.8 ,安装 TCMalloc
  9. PHP常用时间函数总结
  10. 贪心/思维题 UVA 11292 The Dragon of Loowater