开发者

How can I find a TCP port that is free with NetTcpBinding (WCF) (so a server can bind to it)

Find the next TCP port in .Net says how to do this in raw .net, but not how to safely to this with WCF.

In my unit tests, I need to use the NetTcpBinding, I do not wish to hard code the port it is using.

Therefore how can I 开发者_JAVA技巧get the NetTcpBinding to automatically choose a free port when used in my ServiceHost?

How can I get it to tell me the port (or full endpoint address) it has chosen?

Or how can I using .NET find a few port that is valid for a server to bind to?


Given that my bounty did not lead to any new answers, I think we can assume there is no good answer.


You don't need to roll your own port-finding logic - Windows will choose a free port if you specify it as 0. Then you can find out which port was assigned by interrogating the dispatchers, like so:

// 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;


Set the port to zero. That allows the OS to pick an available port for you. If you need to determine which port was used, you can query that from the socket after it has been bound locally.


Here's what I do: start with a random port in range 1025-2000 (range chosen arbitrarily). I try to bind it and if it fails I catch the exception. Then I go one port up (port = port % 2000 + 1025) until I wrap. I no port is bound, I give up failing the test.


4 years later.. at the present day we have a solution, setting ListenUriMode to Unique, as stated from MSDN

Here a little example of an endpoint configuration

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

And now the next problem: If the port is dynamic how can clients know it? As stated in THIS ANSWER you can use WCF DISCOVERY: it requires a little configuration on both server and client side but it works well (with the only problem that it takes some seconds to get it, by default 20 seconds but i have no problems forcing it to 5)


when using a random high port you can generate collisions with other server processes that want to start after your program. just use zero as the port number and let the os care about reservations (/etc/services on unix, don´t know how windows handles it).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜