UDP через NAT (через Интернет) - PullRequest
0 голосов
/ 11 февраля 2019

Я кодирую систему с сервером (за NAT с переадресацией портов UDP, статическим белым IP-адресом) и клиентом (за NAT без каких-либо пользовательских настроек).

Задача - отправка данных с сервера на клиент черезИнтернет.Чтобы сервер знал конечную точку клиента (а клиентский маршрутизатор хранит таблицу трансляции), клиент отправляет каждые 5 секунд простой UDP-запрос на сервер, например «Hello!».Код сервера:

    private void SendData(ref string destination, CancellationToken cancelToken)
    {
        UdpClient senderClient = new UdpClient(AddressFamily.InterNetwork);
        try
        {
            while (true)
            {
                cancelToken.ThrowIfCancellationRequested();
                if (string.IsNullOrEmpty(destination))
                    continue;
                byte[] testMessage = Encoding.UTF8.GetBytes("AnyDatas");

                string ip = destination.Split(':')[0];
                string p = destination.Split(':')[1];
                IPEndPoint clientEP = new IPEndPoint(IPAddress.Parse(ip), int.Parse(p));
                senderClient.Send(testMessage, testMessage.Length, clientEP);
                Thread.Sleep(3000);
            }
        }
        catch (OperationCanceledException ex)
        { }
        finally
        {
            if (senderClient != null)
                senderClient.Close();
        }
    }

    private void ListenConnectionSupport(ref string stClientEP, CancellationToken cancelToken)
    {
        IPEndPoint IpEp = new IPEndPoint(IPAddress.Any, 13001);
        UdpClient listenClient = new UdpClient(IpEp);
        try
        {
            while (true)
            {
                cancelToken.ThrowIfCancellationRequested();
                IPEndPoint cIpEp=null;
                byte[] messageBytes = listenClient.Receive(ref cIpEp);
                if (Encoding.UTF8.GetString(messageBytes) == "UDP-support")
                {
                    stClientEP = String.Format("{0}:{1}",cIpEp.Address,cIpEp.Port);
                }
            }
        }
        catch (OperationCanceledException ex)
        { }
        finally
        {
            if (listenClient != null)
                listenClient.Close();
        }

    }

И это работает даже!Но только если клиент находится под тем же маршрутизатором, несмотря на отправку запроса client-> server на IP-адрес внешнего сервера.

Я использую свой смартфон как маршрутизатор клиента и повторяю попытку (client - это другой компьютер).Но хотя сервер получает Hello-запрос и отправляет ответ, клиент ничего не получает.

ОБНОВЛЕНИЕ -----------------

Мне нужно разработатьСистема для схемы: Сервер (192.168.0.3) -routerA (статический публичный IP, имеет переадресацию портов для сервера) - INTERNET-routerB (любая обычная точка доступа или маршрутизатор) - Клиент

Алгоритм:

  1. Клиент отправляет маршрутизатору A (в этом контексте routerA = Server) «Здравствуйте, передайте мне ваши данные».Для таблицы маршрутизатора клиент отправляет это непрерывно.

  2. Сервер из предыдущего сообщения (например, сервер STUN) может отметить Client EP.

  3. Сервер в WHILE (true) цикл отправляет данные клиенту.

Ошибка «Клиент не получает данные с сервера».

Если это имеет значение

  • сервер слушает порт 13001Клиент знает этот номер порта

  • В случае «одного маршрутизатора» сервер видит конечную точку клиента, например «192.168.0.5» (его локальный IP-адрес), а в случае «двух маршрутизаторов» - конечную точку клиентавыглядит как неизвестный IP (я не знаю, что это такое, его ipconfig показывает другой).

Пожалуйста, покажите мне правильное направление!

...