前言
在网络编程中,通过广播和多播可以实现发送端发送一个数据包,有多个接收端接收的情况。
广播
由于Tcp是有连接的,所以不能用来发送广播消息。发送广播消息,必须用到Udp,Udp可以不用建立连接而发送消息。广播消息的目的IP地址是一种特殊IP地址,称为广播地址。广播地址由IP地址网络前缀加上全1主机后缀组成,如:192.168.1.255是192.169.1.0这个网络的广播地址;130.168.255.255是130.168.0.0这个网络的广播地址。向全部为1的IP地址(255.255.255.255)发送消息的话,那么理论上全世界所有的联网的计算机都能收得到了。但实际上不是这样的,一般路由器上设置抛弃这样的包,只在本地网内广播,所以效果和向本地网的广播地址发送消息是一样的。
C#中发送广播消息的过程如下,注意要调用SetSockOption函数,不然要抛出异常:
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, 9050);//255.255.255.255
IPEndPoint iep2 = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 9050);
string hostname = Dns.GetHostName();
byte[] data = Encoding.ASCII.GetBytes(hostname);
sock.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast, 1);
sock.SendTo(data, iep1);
sock.SendTo(data, iep2);
sock.Close();
C#中接收广播消息的过程如下,没有什么特别的:
Socket sock = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
sock.Bind(iep);
EndPoint ep = (EndPoint)iep;
Console.WriteLine("Ready to receive
…");
byte[] data = new byte[1024];
int recv = sock.ReceiveFrom(data, ref ep);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("received: {0} from: {1}",
stringData, ep.ToString());
data = new byte[1024];
recv = sock.ReceiveFrom(data, ref ep);
stringData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("received: {0} from: {1}",
stringData, ep.ToString());
sock.Close();
Attentions:
1 广播可以由客户程序来通知子网内的服务程序,自己的位置。
2 发送广播消息时指定的端口也是有作用的,接收端的Udp Socket如果Bind到此接口的话,就能够接收到消息。(如果不Bind的话,就能接收所有端口的消息??)
3 接收端接到的包中显示的远端IP地址是发送端的地址。就是说广播地址不会显示到一个包的源IP地址位置(LoopBack地址不会显示到包的目的IP地址位置)
4 可以用线程不停地发送和接收广播消息,确认两端的位置和证明自己的存在
多播(组播)
广播的一个缺点就是,会影响到所有的子网内的计算机,即使对此广播消息不感兴趣的计算机。多播可以解决这个问题。
多播采用推进技术(浏览网页属于拉拔技术,同样属于推进技术的有发送Email服务)。多播也叫组播,如果用户加入某个多播组,那么,它就能够收到发往这个组的数据。
组播应用D类IP地址(224.0.0.0-239.255.255.255),但不是说从每个组播的组接收数据的计算机要具有D类IP地址。组播的组需要D类IP地址来标示。D类IP地址分成几断,某些具有特殊用途。
组播有两种应用模式。一种是一个组中的任意一个用户发信息,其余用户都能够接收,各个用户的地位是等价的。另一种是只一个用户发信息,其余用户只负责接收信息。
组播的拓扑结构是一个树状结构。
组播需要支持组播的硬件,支持组播的Tcp/ip协议栈,支持组播的软件。加入离开一个组播组需要用到SGMP(Simple Group Management Protocol)协议。发送组播信息还有一个TTL(Time To Live)值,使组播信息不会穿过很多的子网边界,默认TTL值是1,即只对本地子网有效。
C#对组播的支持
组播编程需要Udp,有两个类支持组播网络编程Socket,和UdpClient.一台计算机要加入某一个组,接收发往某个组的信息。Socket类要调用SetSocketOption函数加入和离开某一个组。UdpClient类有直接的加入和离开某个组的成员函数可以调用。而向某个组发信息,则没有什么特殊的,只需把发送数据的目的地址设为组播地址就可以了。
问题:
问:一个Udp Server加入某个组播组,然后绑定某个端口,开始接收数据,能接收到哪些数据?
答:可以接收到发往这个组播组这个端口的数据,可以接收到发往这个端口的广播数据,可以接收到专门发往这个端口的单播数据。
问:(1)怎样知道自己周围组播的组的情况(D类IP地址被占用的情况)?(2)自己可否只是通过编程就建立一个组播组?(没有找到资料)
答:(1)还不知道。(2)(不太明白详细具体情况)。是可以的,一个Socket往一个固定的组播地址的端口发送数据,那么一个组播的组就建立起了,其余计算机可以加入此地址标示的组,接收信息。(当然,需要硬件软件协议支持。另外对此组播地址的值也有限制,组播地址也有类似于192.168.0.0网络地址的,只用于局域网,不路由的地址)