2012-01-11 3 views
2

Я использую класс C# UdpClient для UDP-сетей. Существует один объект UdpClient, привязанный к фиксированному локальному порту, но не к какой-либо удаленной конечной точке, поскольку он должен иметь возможность отправлять/получать/с нескольких разных конечных точек.SocketException по неправильной теме

У меня есть два потока: один для отправки, один для приема. Теперь, когда я отправляю данные в конечную точку, которая существует, но не прослушивает этот порт, я ожидаю SocketException. И я его получу. К сожалению, это не мой вызов Send, который возвращает исключение, но вызов Receive. Поэтому в отправляющем потоке я отправляю данные на «недействительную» конечную точку, и мой получающий поток получает исключение. К сожалению, в этот момент я, конечно, не знаю, какая конечная точка вызвала это исключение.

Хранение конечной точки перед отправкой, а доступ к ней в принимающем потоке - это просто ошибка состояния гонки, ожидающая своего появления.

К сожалению, SocketException не дает мне конечной точки, которая вызвала ошибку.

Любые идеи? Как-то возможно сделать исключение брошенным на поток отправки?

справка приветствуется.

+0

Я думаю, что это более или менее по дизайну из-за того, как работает UDP. Предполагая, что он может отправлять данные, то есть правильно инициализироваться.Я считаю это потому, что UDP не выполняет никаких проверок ошибок. Он просто отправляет и забывает. –

+0

Я мог бы жить с этим, если бы он не убил мой вызов Receive(). Так или иначе, это кажется довольно нелогичным. –

+0

Итак, читатель ближе к Документации, это может быть что-то другое. Можете ли вы опубликовать SocketException и SocketException.ErrorCode, чтобы лучше вам помочь. –

ответ

3

Когда вы получаете 0DP-код, он выходит на провод и эффективно исчезает. Вы не должны предполагать, что вы получите какую-либо обратную связь.

Иногда, если в пункте назначения нет слушателя, пункт назначения может быть достаточно любезным, чтобы отправить сообщение ICMP_UNREACH_PORT. Маршрутизаторы между могут быть достаточно добрыми, чтобы доставить это сообщение в вашу операционную систему. Если это произойдет, это будет долго после возврата вашего исходного вызова send(). Для ICMP_UNREACH_PORT ОС обычно кэширует его и сообщает об ошибке в следующий раз, когда вы делаете send() в тот же пункт назначения. Другие сообщения ICMP (вы не указали, какое исключение вы получаете) могут повлиять на другие вызовы.

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

0

Я думаю, что это ожидаемое поведение для UDP. UDP send() не является блокировкой, поэтому он не будет ждать потенциальной ошибки. (Не говоря уже о том, что вы не можете полагаться на сообщения об ошибках, которые надежно принимаются при отправке на активный хост с закрытым портом, - это может быть межсетевым экраном, ограничено по скорости или иным образом сброшено из-за перегрузки и т. Д.)

Вы можете подключить UDP-сокет к определенной удаленной конечной точке, которая выделила бы уникальный номер порта и позволила ОС [наиболее вероятно] отличать ошибки от этой конкретной конечной точки от любого другого случайного хоста. Но опять же, вы не должны полагаться на способность справляться с этими ошибками.

Слишком плохо, что в исключении больше информации. Это похоже на недосмотр в том, как .NET обрабатывает сокеты UDP. Согласно documentation, вам необходимо проверить ErrorCode исключения и соответствующим образом обработать error. (что в вашем случае, вероятно, может означать игнорирование ошибки.)

Смежные вопросы