简体   繁体   English

如何找到NetTcpBinding(WCF)免费的TCP端口(因此服务器可以绑定到它)

[英]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. 在.Net中找到下一个TCP端口,说明如何在原始.net中执行此操作,但不知道如何使用WCF安全地执行此操作。

In my unit tests, I need to use the NetTcpBinding, I do not wish to hard code the port it is using . 在我的单元测试中,我需要使用NetTcpBinding, 我不希望硬编码它正在使用的端口

Therefore how can I get the NetTcpBinding to automatically choose a free port when used in my ServiceHost? 因此,如何在我的ServiceHost中使用NetTcpBinding时自动选择一个空闲端口?

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? 或者我如何使用.NET找到一些对服务器有效的端口?


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: 您不需要滚动自己的端口查找逻辑 - 如果您将其指定为0,Windows将选择一个空闲端口。然后您可以通过询问调度程序找出分配的端口,如下所示:

// 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). 这是我的工作:从1025-2000范围内的随机端口开始(任意选择范围)。 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. 然后我去一个端口( port = port % 2000 + 1025 ),直到我换行。 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 4年后..在今天我们有一个解决方案,将ListenUriMode设置为Unique ,如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) 正如本答案中所述,您可以使用WCF DISCOVERY :它需要在服务器端和客户端都进行一些配置,但它运行良好(唯一的问题是它需要几秒钟才能获得它,默认为20秒,但我没有问题强制它到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). 只需使用零作为端口号,让os关心预留(unix上的/ etc / services,不知道windows如何处理它)。

目前我认为这是不可能的,感谢所有提供工作的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM