C# UDP 客户端读取多播 IP(本地接口),并将单播 UDP 发送到 ***

Posted

技术标签:

【中文标题】C# UDP 客户端读取多播 IP(本地接口),并将单播 UDP 发送到 ***【英文标题】:C# UDP client reading multicast IP (local interface), and sending unicast UDP to *** 【发布时间】:2018-11-20 21:52:07 【问题描述】:

我有一个 *** 客户端,它可以很好地通过 *** 管道发送单播 UDP 数据包,但不能用于多播 IP (UDP) 数据包 (Open***)。所以我想我可以编写这个小垫片,它将 IP(端口 3000)多播并通过 *** 作为单播发送。

我看到多播数据包到达,但我没有看到 *** 端到达(WireShark 没有帮助,因为与 IpConfig /all 不同)它看不到 *** 接口。)。

我认为我的问题可能是我不太清楚 BIND 和 CONNECT 之间的区别,以及我应该将 UDPClient 绑定到哪个接口(*** 或本地)。

命令行是:

239.0.0.0 198.168.0.15 10.4.30.239 172.27.225.77
arg[0] = multicast from address
arg[1] = unicast to address
arg[2] = local physical ethernet assigned address
arg[3] = virtual address of computer on *** network (client)

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace MUTunnel

    public class EchoBot
    
        protected UdpClient sender;
        protected UdpClient listener;

        protected const int listenPort = 3000;
        protected const int outPort = 3000;

        protected IPEndPoint inPoint;
        protected IPEndPoint outPoint;
        protected IPAddress listenAddress;
        protected IPAddress sendAddress;
        protected IPAddress localAddress;
        protected IPAddress ***Address;

        public EchoBot(string from, string to, string local, string ***)
        
            bool parsed = IPAddress.TryParse(from, out listenAddress);
            parsed = IPAddress.TryParse(to, out sendAddress) && parsed;
            parsed = IPAddress.TryParse(local, out localAddress) && parsed;
            parsed = IPAddress.TryParse(***, out ***Address) && parsed;
            if (!parsed)
            
                System.Console.WriteLine("Usage: MUTunnel <source multicast IP> <dest unicast IP> <local host IP address> <*** IP address>");
                Environment.Exit(1);
            
            listener = new UdpClient();
            listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            inPoint = new IPEndPoint(localAddress, listenPort);
            listener.Client.Bind(inPoint);
            listener.JoinMulticastGroup(listenAddress);

            sender = new UdpClient();
            sender.Ttl = 64;
            sender.AllowNatTraversal(true);
            //outPoint = new IPEndPoint(sendAddress, outPort);
            sender.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            sender.Connect(sendAddress, outPort);
        

        public void send(byte[] bytes)
        
            sender.Send(bytes, bytes.Length);
        
        public void loop()
        
            bool done = false;
            try
            
                while (!done)
                
                    byte[] bytes = listener.Receive(ref inPoint);
                    Console.WriteLine("Received Multicast from  0 : length 1\n", listenAddress.ToString(), bytes.Length);
                    this.send(bytes);
                
            
            catch (Exception e)
            
                Console.WriteLine(e.ToString());
            
            finally
            
                listener.Close();
                sender.Close();
            
        
    

    class Program
    
        static void Main(string[] args)
        
            if (args.Length != 4)
            
                System.Console.WriteLine("Usage: MUTunnel <source multicast IP> <dest unicast IP> <local host IP address> <*** IP address>");
                Environment.Exit(1);
            
            EchoBot echoBot = new EchoBot(args[0], args[1], args[2], args[3]);
            Console.WriteLine("MUTunnel Waiting for messsages...");
            echoBot.loop();
        
    

ipconfig /all 如下(Open*** 客户端运行时)

P:\>ipconfig /all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : YSG4206
   Primary Dns Suffix  . . . . . . . : draper.com
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : draper.com

Ethernet adapter Ethernet 3:

   Connection-specific DNS Suffix  . : draper.com
   Description . . . . . . . . . . . : Killer E2200 Gigabit Ethernet Controller
   Physical Address. . . . . . . . . : F8-B1-56-FF-8B-36
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   IPv4 Address. . . . . . . . . . . : 10.4.30.239(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.254.0
   Lease Obtained. . . . . . . . . . : Monday, June 18, 2018 5:28:03 PM
   Lease Expires . . . . . . . . . . : Thursday, June 21, 2018 8:46:50 PM
   Default Gateway . . . . . . . . . : 10.4.31.254
   DHCP Server . . . . . . . . . . . : 140.102.100.111
   DNS Servers . . . . . . . . . . . : 10.10.20.11
                                       10.10.20.12
   NetBios over Tcpip. . . . . . . . : Enabled

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : TAP Adapter OAS NDIS 6.0
   Physical Address. . . . . . . . . : 00-FF-91-E7-8A-38
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   IPv4 Address. . . . . . . . . . . : 172.27.225.77(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :
   NetBIOS over Tcpip. . . . . . . . : Enabled

P:\>

更新

已添加 发件人.TTL = 64; sender.AllowNatTraversal(true); 还在选择 *** 接口的客户端上运行 RawCap。数据包转储不显示我正在转换为单播并尝试发送到 129.168.0.15 的多播数据包进入该接口。

只是一些其他的东西。 (请参阅 RawCap 中 .pccap 文件的 wireshark 显示。

【问题讨论】:

Bind 本地,Connect 远程。您对绑定/连接的使用似乎很好。但是,您阅读了 ***address,但从未将其用于任何事情? @NickDechiara 是的。我尝试将其绑定到本地 *** 地址(由 IPConifg 报告),但这会引发错误。我见过其他人只是连接 UDP 客户端,而这似乎对他们有用。但我确实有两个接口。 您真的看到“收到来自 .. 的多播”消息吗?在 Windows 上,我认为您只能将侦听器绑定到任何地址(0.0.0.0)并获得多播,您可以选择与多播地址绑定的任何其他操作系统以避免不相关的流量。 是的。我看到“收到来自 .. 的多播”消息。是的,内容是预期的。 No Wireshark 在客户端看不到 *** 接口,所以我无法判断 UDP 单播是否正在离开。我确实看到 *** 服务器没有收到任何东西(至少 tcpdump 没有看到它)。 sender.Ttl = 16; 看起来有点严格;如果你增加它会发生什么,例如255?我的意思是,听起来您在数据包神秘消失时遇到了麻烦,.Ttl 的工作是指定一个数据包在被丢弃之前可以经过多少跳。 16 个跃点异常低(至少按照 Wikipedia 引用的建议从默认 64 开始),并且可能使用 *** 将更多跃点添加到路径中。 【参考方案1】:

我怀疑你没有任何东西在收听你的单播的另一端。

单播是用于描述通信的术语,其中一段 信息从一个点发送到另一个点。在这种情况下 只有一个发送者,和一个接收者

我添加了一个额外的侦听器来侦听发送端点,一切正常,并将打印出发送的消息。

在 ip:198.168.0.15 的电脑上运行额外的监听器

IPAddress localAddress = IPAddress.Parse("198.168.0.15");
const int listenPort = 3000;

var listener = new UdpClient();
listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
var inPoint = new IPEndPoint(localAddress, listenPort);

listener.Client.Bind(inPoint);

while (true)

    byte[] bytes = listener.Receive(ref inPoint);
    Console.WriteLine("Received Message from  0 : message 1\n", localAddress.ToString(),Encoding.ASCII.GetString(bytes));
    Thread.Sleep(1000);

【讨论】:

我确实有一个听众。我还应该看到数据包通过 TCP 转储到达目标(因为它是 Centos 计算机)。侦听器适用于源自私有云的所有流量。我想做的是让它适用于通过 *** 传输的东西。 你能通过 *** ping 那台 centOS 电脑吗?您可以通过该 IP 上的 *** SSH 进入那台计算机吗? 你也试过启用 sender.AllowNatTraversal = true; msdn.microsoft.com/en-us/library/… 您确定这不是网络/*** 配置问题吗? serverfault.com/questions/608517/… 不确定是否不是 *** 配置错误。但是请参阅我对注释的最新添加(我添加了 sender.AllowNatTransversal。以及 RawCAP 的结果

以上是关于C# UDP 客户端读取多播 IP(本地接口),并将单播 UDP 发送到 ***的主要内容,如果未能解决你的问题,请参考以下文章

UDP:从所有网络接口读取数据

UDP 单播广播多播

TCP/IP||UDP广播和多播

多播程序设计(基于UDP协议)

绑定多播 (UDP) 套接字是啥意思?

TCP/IP详解 笔记九