雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

在Linux中使用C#(mono)进行组播通讯时如何绑定到指定网卡

2024-08-06 42

前言

在另外一篇文章中介绍了不在一个子网的组播通讯 ,对于有多个网卡的系统来说,不同网卡的网络可能并不是同一个,组播通讯需要指定到需要通讯的网络中,也就需要指定到特定网卡了。

如何将组播绑定到指定网卡?

Windows中指定组播网卡

前段时间写了一个在windows中的程序,只需要对组播的socket如下设置即可见组播指定到需要的网卡:

udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                                      new MulticastOption(IPAddress.Parse(230.0.0.88), IPAddress.Parse(192.168.1.88)));
            udpServerSocket.Bind(new IPEndPoint(IPAddress.Parse(192.168.1.88), 18888));

其中192.168.1.88是网卡的IP地址。
通过以上设置之后,在Windows中测试,就可以将组播指定到IP地址对应的网卡了。

Linux中指定组播网卡

在Linux中通过mono,也可以运行C#的程序。
虽然,可以将windows中运行的程序直接放到Linux中运行,但组播配置有些许差异,实际测试在Linux中,需要这样配置:

    udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, 
                                                            IPAddress.Parse(192.168.1.88).GetAddressBytes());
    udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, 
                                                            new MulticastOption(IPAddress.Parse(230.0.0.88), IPAddress.Any));
    udpServerSocket.Bind(new IPEndPoint(IPAddress.Any, 18888));           

这三个配置,后两个Windows中也配置了,但Linux如果做一样的配置,则接收不到组播消息(原因暂时未知,可能和mono内部的实现,或者Linux网络通讯的底层有关吧)。
以下给出Linux中组播通讯的全部配置和通讯的参考代码。

    Socket udpServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

    udpServerSocket.MulticastLoopback = false;
    udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 64);
    
    udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, 
                                                            IPAddress.Parse(192.168.1.88).GetAddressBytes());
    udpServerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, 
                                                            new MulticastOption(IPAddress.Parse(230.0.0.88), IPAddress.Any));
    udpServerSocket.Bind(new IPEndPoint(IPAddress.Any, 18888));           


    byte[] buf = new byte[1024];
    var txEdp = new IPEndPoint(IPAddress.Parse(230.0.0.88), 18888);
    udpServerSocket.SendTo(Encoding.Default.GetBytes(Test!), txEdp);

    while (true)
    {
        EndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
        int recvCount = udpServerSocket.ReceiveFrom(buf, ref endpoint);
        Console.WriteLine(Receive {0} bytes from {1}., recvCount, endpoint);
        Console.WriteLine(Receive message: {0}, Encoding.Default.GetString(buf));

        var sendMsg = Hi:  + DateTime.Now.TimeOfDay.ToString();
        txEdp = new IPEndPoint(IPAddress.Parse(230.0.0.88), (endpoint as IPEndPoint).Port);
        udpServerSocket.SendTo(Encoding.Default.GetBytes(sendMsg), txEdp);
        Console.WriteLine(Send \Hi!\ to {0}., txEdp);
    }

结语

以上给出了在Linux中通过mono运行C#程序时,使用组播通讯应该如何配置才能制定到特定的网卡,虽然都是C#的程序,但实测发现在Windows和Linux中有一定差异,好在都能实现需要的组播通讯的功能。

更新于:3个月前
赞一波!

文章评论

评论问答