FCL应用技巧之------实现UDP组播

1 组播原理

组播的概念是在IP层定义的,一些特殊的IP地址被规定为组播IP地址,不能配置为某个主机的IP。具体说来,组播使用的IP地址是整个D类地址,即:

FCL应用技巧之------实现UDP组播_第1张图片

整个D类地址是不能配置到主机网卡上的,它们专门供组播使用。

2 FCL中实现UDP组播的两种方式

FCL为使用UDP提供了两个类,一个是基础的Socket,一个是封装了Socket的UdpClient。需要说明的是,组播的特殊性只是在接收方才存在,对于发送方,直接向组播IP地址发送即可,与单播无异。

发送程序如下:

class Program
    {
        private static UdpClient client = new UdpClient(6000);
        static void Main(string[] args)
        {
            byte[] bytes = Encoding.UTF8.GetBytes("hello");
            while (true)
            {
                Thread.Sleep(1000);
                client.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Parse("224.0.0.101"), 6005));
            }
        }
    }

2.1 使用UdpClient

由于UdpClient对Socket进行了很好的封装,所以使用起来比较方便,本身就提供了加入组播组的方法。代码如下:

public class UDPMulticastListener
    {
        public static void Main(String[] args)
        {
            UdpClient udpClient = new UdpClient(6005);
            udpClient.JoinMulticastGroup(IPAddress.Parse("224.0.0.101"));
            IPEndPoint remoteEp = new IPEndPoint(IPAddress.Any, 0);
            while (true)
            {
                Byte[] buffer = udpClient.Receive(ref remoteEp);
                String msg = Encoding.UTF8.GetString(buffer);
                Console.WriteLine(msg);
            }
        }
    }
MSDN上提醒:调用JoinMulticastGroup之前,必须为udpClient绑定了端口。

2.2 使用Socket

Socket提供了最基础和灵活的控制,需要通过SetSocketOption()方法来加入组播组。代码如下:

public class UDPMulticastListener
    {
        public static void Main(String[] args)
        {
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            listener.Bind(new IPEndPoint(IPAddress.Any, 6005));
            MulticastOption mcastOption = new MulticastOption(IPAddress.Parse("224.0.0.101"), IPAddress.Parse("172.16.35.220"));

            listener.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption);

            while (true)
            {
                byte[] buffer = new byte[1024];
                int n = listener.Receive(buffer);
                String msg = Encoding.UTF8.GetString(buffer, 0, n);
                Console.WriteLine(msg);
            }
        }
    }
需要注意的是,指定MulticastOption的时候,必须为其指定要使用网卡源IP地址,否则组播不能成功。

3 抓包分析以太网中UDP组播实现

通过上面实例可以看出,在C#中使用组播非常简单。组播在以太网中是如何实现的呢?
首先,与IP地址一样,以太网中的MAC地址也有一部分专门供组播使用,他们的特征是最高字节的最低位是1,这些MAC地址不能作为网卡的MAC,只能是组播MAC。对这些MAC的处理是这样的:交换机会把目的MAC是组播MAC的包转发到同一VLAN的所有端口,主机上的网卡不仅接收目的MAC是自己Mac的,也接收目的MAC是组播MAC的包,然后把收到的包剥去以太层交给IP层、UDP层继续处理。在IP层,如果发现目的IP是组播IP,并且本机已加入了这个组播组,则交由对应的应用程序处理,否则丢弃。

关于组播IP于组播MAC的对应规则有专门的规定。关于组播有一篇英文妙文,http://www.firewall.cx/networking-topics/general-networking/107-network-multicast.html。

你可能感兴趣的:(FCL应用技巧之------实现UDP组播)