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

标签 c# multicast udpclient windows-networking

我有一个 VPN 客户端,它可以很好地通过 VPN 管道发送单播 UDP 数据包,但不能对多播 IP (UDP) 数据包 (OpenVPN) 执行此操作。所以我想我可以写这个小垫片,它将采用 IP(端口 3000)多播并将它们作为单播通过 VPN 发送。

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

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

命令行是:

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 VPN 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 vpnAddress;

        public EchoBot(string from, string to, string local, string vpn)
        {
            bool parsed = IPAddress.TryParse(from, out listenAddress);
            parsed = IPAddress.TryParse(to, out sendAddress) && parsed;
            parsed = IPAddress.TryParse(local, out localAddress) && parsed;
            parsed = IPAddress.TryParse(vpn, out vpnAddress) && parsed;
            if (!parsed)
            {
                System.Console.WriteLine("Usage: MUTunnel <source multicast IP> <dest unicast IP> <local host IP address> <vpn 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> <vpn 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 内容如下(OpenVPN 客户端运行时)

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); 还在选择了 VPN 接口(interface)的客户端上运行 RawCap。数据包转储没有显示我正在转换为单播并尝试发送到进入该接口(interface)的 129.168.0.15 的多播数据包。

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

enter image description here

最佳答案

我怀疑你没有监听单播的另一端。

Unicast is the term used to describe communication where a piece of information is sent from one point to another point. In this case there is just one sender, and one receiver.

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

在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);
}

关于C# UDP 客户端读取组播 IP(本地接口(interface)),并将单播 UDP 发送到 VPN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50801239/

相关文章:

java - 如何在 Java 中重新加入多播组

c# - 杀死阻塞的 UDP 套接字

c# - 从同一类型的另一个对象更新 Entity Framework 对象

c# - 在 ViewModel 中处理对话框的最佳方式是什么?

c# - 在同一个 MVC 6 Controller 中组合 API Controller 调用和 Controller 调用

c++ - 在具有多个接口(interface)的linux主机上接收多播

c# - Visual Studio 2010 在 Designer.cs 中硬编码不需要的值

java - 多播数据包未正确到达 podman 内部。已找到解决方法,但不清楚是防火墙问题还是 podman 问题?

java - 连接到 UDP 服务器时获取 PC 设备的唯一字符串(例如 IP 地址)

c# - Service Fabric 无状态服务器自定义 UDP 监听器