Как я могу найти порт TCP, который свободен с NetTcpBinding (WCF) (чтобы сервер мог привязаться к нему) - PullRequest
9 голосов
/ 26 ноября 2009

Найти следующий порт TCP в .Net говорит, как сделать это в raw .net, но не как безопасно сделать это с WCF.

В моих модульных тестах мне нужно использовать NetTcpBinding, Я не хочу жестко кодировать порт, который он использует .

Следовательно, как я могу получить NetTcpBinding для автоматического выбора свободного порта при использовании в моей ServiceHost?

Как мне узнать, какой порт (или полный адрес конечной точки) он выбрал?

Или как с помощью .NET найти несколько портов, которые могут быть привязаны к серверу?


Учитывая, что моя награда не привела к каким-либо новым ответам, я думаю, мы можем предположить, что нет хорошего ответа.

Ответы [ 6 ]

9 голосов
/ 28 июля 2014

Вам не нужно накатывать свою собственную логику поиска портов - Windows выберет свободный порт, если вы укажете его как 0. Затем вы можете узнать, какой порт был назначен, опросив диспетчеров, например:

// Specify port 0, this will cause Windows to choose a free port
var baseUri = new Uri("net.tcp://" + Dns.GetHostEntry("").HostName + ":0");
host = new WebServiceHost(typeof(MyService));
var endPoint = host.AddServiceEndpoint(typeof(IMyService), new NetTcpBinding(), baseUri);

 // Tell WCF to actually bind to a free port instead of 0
 endPoint.ListenUriMode = ListenUriMode.Unique;

 host.Open();

 // Now that the host has bound to a specific port, we can find out which one it chose
 return host.ChannelDispatchers.First().Listener.Uri;
4 голосов
/ 06 января 2010

Установить порт на ноль. Это позволяет ОС выбирать для вас доступный порт. Если вам нужно определить, какой порт был использован, вы можете запросить его из сокета после того, как он был привязан локально.

2 голосов
/ 24 июня 2014

4 года спустя .. в настоящее время у нас есть решение, устанавливающее ListenUriMode в Unique, как указано в MSDN

Вот небольшой пример конфигурации конечной точки

<endpoint address="service"
          binding="netTcpBinding"
          contract="Iservice"
          name="TcpBinding"
          bindingConfiguration="netTcpBindingNoSec"
          listenUriMode="Unique"
          />

А теперь следующая проблема: если порт динамический, как клиенты могут это знать? Как указано в ЭТОМ ОТВЕТЕ , вы можете использовать WCF DISCOVERY : требуется небольшая настройка как на стороне сервера, так и на стороне клиента, но она работает хорошо (единственная проблема - получение нескольких секунд это, по умолчанию 20 секунд, но у меня нет проблем, заставляя его 5)

2 голосов
/ 26 ноября 2009

Вот что я делаю: начать со случайного порта в диапазоне 1025-2000 (диапазон выбран произвольно). Я пытаюсь связать это, и если это терпит неудачу, я ловлю исключение. Затем я иду на один порт вверх (port = port % 2000 + 1025), пока не заверну. Я не привязан ни к одному порту, я сдаю провал теста.

1 голос
/ 01 декабря 2009

при использовании случайного порта высокого уровня вы можете создавать конфликты с другими процессами сервера, которые хотят запускаться после вашей программы. просто используйте ноль в качестве номера порта и позвольте операционной системе заботиться о резервировании (/ etc / services в unix, не знаю, как Windows это обрабатывает).

0 голосов
/ 30 сентября 2010

В настоящее время я считаю, что это невозможно, спасибо всем, кто предоставил работу раундами.

...