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

时间:2018-02-22 12:26:41

标签: c# sockets networking udp

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

我目前遇到的问题是,当UDP数据包在侦听端口上发送到我的公共IP时,它们没有被接收,但是如果我将公共IP更改为我的路由器ip(192.168.0.2) )然后它工作正常。这不是我想要的,因为托管服务器只能发送到客户端的公共IP。

过程

发件人(“5.5.5.5”,1000)通过UDP将数据发送到给定端点(“1.2.3.4”,1000)

服务器开启(“1.2.3.4”,1000)接收数据

使用公共IP和侦听端口(“5.5.5.5”,1000)将数据回送给发件人

为什么数据没有被发送回公共IP,即使它正在侦听给定的端口?

在本地测试时,在同一台机器上运行服务器和客户端,当端点设置为我的公共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 /端口,但是客户端没有监听接收端口所以我用发件人的地址和它应该监听的端口创建一个新的端点。那么游戏或其他应用程序如何通过UDP从客户端 - 服务器进行持续通信来管理它。

1 个答案:

答案 0 :(得分:2)

欢迎来到NAT遍历的世界。 IP地址被翻译并且端口号不能一致地映射的地方。

您正在尝试的内容称为NAT Hairpinning。因此,NAT后面的客户端节点会尝试发送到自己的公共IP地址。 并非所有NAT都支持此模式。。这就是为什么发送到您的私有IP地址,但不是您的公共IP地址。当您的NAT收到数据报的IP地址发往其自己的公共IP时,它不知道它管理的多个节点中的哪个节点将其发送回(您的电脑,手机,游戏机等)。所以它只是丢弃了数据包。