提问者:小点点

为什么我的UDP数据包在发送到我自己的公共IP时没有收到?


我有一个简单的C#UDP服务器,它在不同的线程上运行一个侦听器和一个发送器。侦听器在指定端口上绑定到当前计算机,并侦听任何传入的UDP数据包。编写器会将数据发送到给定的endpoint,这在某些情况下是可行的。

我现在遇到的问题是,当UDP数据包在侦听端口上发送到我的公共IP时,它们不会被接收,但是,如果我将公共IP更改为我的路由器IP(192.168.0.2),那么它就可以正常工作。这不是我要找的,因为托管服务器只能发送到客户端的公共IP。

流程

发送方(5.5.5.5″,1000)通过UDP将数据发送到给定endpoint(1.2.3.4″,1000)

服务器(1.2.3.4″,1000)接收数据

使用发件人的公共IP和侦听端口(5.5.5.5″,1000)将数据回传给发件人

为什么即使在给定端口上侦听,数据也没有被发送回公共ip?

当本地测试时,在同一台机器上运行服务器和客户端,当endpoint设置为我的公共IP和侦听端口时,本地根本无法接收数据。

  Program()
    {

        ipep = new IPEndPoint(IPAddress.Any, 1000);
        listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        listenSocket.Bind(ipep);//this should bind to port 1000


        Thread listenThread = new Thread(listen);
        Thread writeThread = new Thread(send);

        listenThread.Start();
        writeThread.Start();

        listenThread.Join();
        writeThread.Join();

    }

    void listen()
    {
        Console.WriteLine("Starting listener for echoback...");
        while (true)
        {
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint epSender = (EndPoint)sender;
            byte[] buffer = new byte[1024];

            listenSocket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epSender);

            string receivedString = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
            Console.WriteLine("Received via UDP: " + receivedString);
        }

    }

    void send()
    {
        while (true)
        {
            byte[] msg = Encoding.ASCII.GetBytes("Test message".ToCharArray());
//when this is router IP 192.168.0.2, it works fine, but not for public ip
            UdpClient client = new UdpClient("PUBLIC IP", 1000);
            client.Send(msg, msg.Length);

            Thread.Sleep(2000);

        }

    }
}

我注意到当UDP数据包被“服务器”接收时,发送端口总是不同的,我读到你需要在这个IP/端口上回复,但是客户端没有在接收端口上侦听,所以我用发送端的地址和它应该侦听的端口创建了一个新的endpoint。那么,在客户端-服务器通过UDP不断进行通信的情况下,游戏或其他应用程序如何管理这个问题。


共1个答案

匿名用户

欢迎来到NAT遍历的世界。其中IP地址被转换,端口号不能一致地映射。

你正在尝试的是被称为纳特发夹。NAT后面的客户端节点试图发送到自己的公共IP地址。不是所有的NAT都支持这个模式…这就是为什么发送到您的私有IP地址工作,但不是您的公共IP地址。当您的NAT接收到带有指定到其自己的公共IP的IP地址的数据报时,它不知道要将其发送回众多节点中的哪一个(您的pc,您的电话,您的游戏机等。。。)。所以它只是丢弃数据包。