пакет udp не приходит через - PullRequest
       38

пакет udp не приходит через

2 голосов
/ 29 февраля 2012

У меня есть следующие настройки:

Выделенный сервер -> Интернет -> Модем (теленет) -> Маршрутизатор -> клиент

  1. Клиент инициирует tcp-соединение с сервером, чтобы зарегистрироваться на сервере, и предоставляет следующую информацию:
    • mac адрес клиента
    • внешний ip; это получается с помощью загрузки строки веб-клиента с whatsmyip.org
  2. Некоторые обновления происходят на сервере, и, конечно, клиент должен быть уведомлен, поэтому клиент может начать сеанс синхронизации самостоятельно:
    • Чтобы уведомить клиента, сервер отправляет пакет udp с сервера на модем (на внешний ip, ранее полученный от клиента) , в то время как клиент прослушивает пакеты udp позади роутер.

Проблема в том, что я не получаю никаких пакетов. Возможен ли мой сценарий, что мне делать?

Требования:

  • Решить это, включив переадресацию портов на маршрутизаторе, не вариант
  • На сервере установлен фиксированный ip
  • Клиент может быть отключен от Интернета, время от времени
  • Решение должно работать на разных типах маршрутизаторов
  • Оба порта, на которых отправляются и принимаются пакеты, одинаковы
  • Все программирование выполняется на C #
  • Сервер уведомляет клиента, когда происходит обновление, клиент может никогда не опросить сервер на наличие обновлений для предотвращения перегрузки (в случае, если несколько клиентов делают это одновременно)

Приветствует Даана и заранее спасибо

РЕДАКТИРОВАТЬ:
Пример кода с сервера:

UdpClient udpSender = new UdpClient();
IPEndPoint localServerGateway = new IPEndPoint(IPAddress.Parse(externalIp), 8003);
string message = "testmessage";
byte[] messageBytes = Encoding.ASCII.GetBytes(message);
try
{
     udpSender.Send(messageBytes, messageBytes.Length, localServerGateway);
}
catch (Exception error)
{
     Console.WriteLine("Error while sending message: " + error.ToString());
}
udpSender.Close();

Пример кода от клиента:

private void listenForMasterSyncRequest()
{
        bool done = false;
        IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 8003);

        try
        {
            while (!done)
            {
                byte[] bytes = masterSyncUdpListener.Receive(ref groupEP);
                handleMessage(bytes, bytes.Length, true); // handles incoming messages, this is never reached because no packets are received :-(
            }

        }
        catch (Exception e)
        {
            Console.WriteLine("An error occured while listening to server broadcast updates: " + e.ToString());
        }
        finally
        {
            masterSyncUdpListener.Close();
        }
    }

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

NAT работает, устанавливая сеансы между внешним и внутренним хостами. Но сеанс должен быть инициирован на внутренней стороне, а в вашем случае это на стороне клиента. Таким образом, он должен работать так, что клиент должен опросить сервер, отправив пакет UDP на определенный порт на сервере, спрашивая, нужна ли синхронизация. Сервер должен отправить ответ UDP с того же порта обратно на тот же порт, на который клиент отправил исходный запрос. Если вы сделаете это таким образом, пакеты с сервера будут проходить, иначе они не будут проходить. Я знаю, что это работает, потому что именно так работают DNS-запросы из-за NAT.

1 голос
/ 29 февраля 2012

Поскольку у вас нет контроля над устройствами NAT в пути, единственный разумный способ - использовать TCP в качестве основного транспорта.

...