侧边栏壁纸
  • 累计撰写 119 篇文章
  • 累计创建 60 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

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

码峰
2022-09-26 / 0 评论 / 0 点赞 / 96 阅读 / 690 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-09-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

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

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

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中有一定差异,好在都能实现需要的组播通讯的功能。

0

评论区