Двунаправленный / Loopback UDP в .net - PullRequest
2 голосов
/ 17 мая 2010

У меня есть приложение, которое должно передавать и получать через один и тот же порт. Это может произойти в двух случаях:

  • Где ПК общается с удаленным оборудованием. Он «отвечает отправителю», поэтому датаграммы возвращаются на мой компьютер через порт отправки.

  • Когда компьютер разговаривает сам с собой (режим обратной связи) для тестирования и демонстрации (тестовое приложение передает поддельные данные в наше основное приложение через UDP).

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

Может ли кто-нибудь помочь сузить мой поиск, предложив «правильный» способ реализации UdpClient (ов) для надежной обработки вышеуказанных ситуаций?

(Единственное решение, которое я нашел для надежной работы с удаленным оборудованием, - это использование одного UdpClient в двух направлениях, хотя я работаю с устаревшим кодом, который может влиять на это обнаружение. Я пытался использовать два UdpClients, но они наступают друг другу на ноги - В некоторых случаях, когда один клиент запущен, другой клиент не может подключиться. С помощью ExclusiveAddressUse / ReuseAddress, настроенного для обеспечения общего доступа к портам, я могу почти заставить его работать, кроме Приемник должен начать сначала)

1020 * редактировать *

Для уточнения:

Мы общаемся с внешним оборудованием через UDP. Когда он получает от нас сообщение, он отвечает на адрес источника, поэтому мы получаем сообщения обратно на тот же порт. Эта часть работает нормально.

Однако, если я попытаюсь эмулировать внешнее оборудование с помощью обратной связи (т.е. я отправляю и получаю через один и тот же порт «себе»), я могу получать дейтаграммы только в том случае, если я начинаю получать до того, как начну передачу. Это прекрасно работает - но если я передаю, а затем пытаюсь получить, я никогда не получаю никаких данных. То, что я на самом деле пытаюсь отправить, в данном случае не имеет значения.

Итак, у меня две проблемы:

1) Как надежно работать с обратной связью.

2) Как это сделать (1), не прерывая внешнюю связь, которая в настоящее время работает нормально!

Поскольку я попробовал все виды комбинаций 1 или 2 UdpClients и множество различных настроек (безрезультатно), мне просто стало интересно, удалось ли кому-нибудь заставить петлю UPD работать хорошо, поскольку это может дать мне привести к решению, которое я могу работать во всех случаях.

Спасибо, что нашли время подумать об этом ...

Ответы [ 3 ]

5 голосов
/ 24 мая 2010

Это по замыслу.

UDP-соединение меньше по сравнению с TCP, для которого требуется соединение.

При отправке данных из UDP они транслируются. Это означает, что он будет доступен только получателю, который жив во время вещания.

Пример:

TCP похож на телефонный звонок. Звонящий звонит получателю. Приемник принимает вызов, и связь происходит. Если приемник недоступен, вызывающий абонент получит сообщение об ошибке (вызывающий абонент - клиент, а получатель - сервер, прослушивающий порт)

UDP похож на FM-радиовещание. Песня транслируется по радио независимо от того, слушает ли кто-то на другом конце или нет. Если приемники включили радио, они получат песню. Если песня передается в 10:30, а мой радиоприемник включен в 10:30, я могу услышать песню. Но если я включу мой райдо в 10:35, это значит, что я пропустил его и не смогу услышать его снова.

Обновление

Как я вижу, реальная проблема заключается в передаче по порту 1111 (например), хотя вы пытаетесь достичь приложения X и получать через порт 1111 через приложение Y на том же компьютере.

Для того же я могу предложить 2 обходных пути (не хорошо, но выполнимо).

  1. Как вы сказали, если вы запускаете передатчик после запуска приемника, все в порядке. Так что просто попытайтесь периодически вводить логику перезапуска передатчика.

  2. Передача и прием на 2 порта каждый раз. например. 1111 и 2222. Удаленное оборудование будет использовать первый набор 1111, а приложение демо-версии будет использовать 2222.

3 голосов
/ 24 мая 2010

Так что я думаю, что понимаю вашу проблему.

У вас есть

1- Клиентское приложение, которое отправляет данные UDP на аппаратное устройство, которое принимает, скажем, через порт 1234, в то же время это приложение также получает ответы через порт 1234.

2 - аппаратное устройство, которое получает данные UDP через порт 1234 и отвечает отправителю через порт 1234.

Таким образом, когда вы эмулируете аппаратное устройство, использующее на одной и той же машине, вы получаете клиентское приложение и аппаратный эмулятор, которые прослушивают UDP-пакеты с одного и того же IP-адреса 127.0.0.1 и порта 1234?

Я захватил суть того, что у вас есть?

Если это так, рассматривали ли вы вопрос о добавлении второго IP-адреса к машине. Это не означает, что вам нужно иметь 2 сетевые карты, одна сетевая карта может иметь несколько IP-адресов. Таким образом, вы можете иметь два «устройства» на отдельном интерфейсе, которые должны преодолевать любые конфликты, имеющие оба на одном интерфейсе.

Например, если у вас есть два IP-адреса 192.168.0.5 и 192.168.0.6.

Клиентское приложение может быть отправлено на 192.168.0.6 и получено на 192.168.0.5 в то время как аппаратный эмулятор получает на 192.168.0.6 и отвечает на 192.168.0.5.

Вот ссылка, чтобы описать, как добавить дополнительные IP-адреса.
http://www.itsyourip.com/networking/how-to-add-multiple-ip-address-in-windows-2000xp2003/

Это для 2000 / XP / 2003, но процесс похож на Vista и Windows 7.

0 голосов
/ 05 февраля 2011

После долгого отсутствия этого кода я получил возможность еще раз взглянуть на него и разработал смущающее тривиальное решение этой проблемы.

Оказывается, клиентский код, вызывающий мой класс UDP, настраивал его для передачи и получения. Поэтому вместо передатчика с доступом для записи и приемника с доступом для чтения у меня фактически был передатчик с возможностью чтения / записи и приемник с возможностью чтения / записи.

Это означало, что, если передатчик был инициализирован первым, он также попытался бы получить через этот порт и таким образом захватил бы все переданные дейтаграммы. Когда приемник подключался, он никогда не получал никаких данных просто потому, что он использовался передатчиком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...