如何使用NetTcpBinding(WCF)找到一个可用的TCP端口(以便服务器可以绑定它)

9

在 .Net 中找到下一个 TCP 端口 介绍了如何在原始的 .net 中实现,但没有说明如何在 WCF 中安全地实现。

在我的单元测试中,我需要使用 NetTcpBinding,但我不想硬编码它使用的端口

因此,当我在 ServiceHost 中使用 NetTcpBinding 时,如何让它自动选择一个空闲端口?

如何让它告诉我它选择的端口(或完整的终结点地址)?

或者,如何使用 .NET 找到一个对服务器绑定有效的端口?


考虑到我的赏金并没有带来任何新的答案,我们可以认为目前没有好的答案。


2
请将Matt的帖子标记为答案。它绝对有效,以便新访客清楚明白。 - Florian Tischler
5个回答

11

如果您将端口指定为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;

4

将端口设置为零。这样操作系统可以为您选择一个可用的端口。如果您需要确定使用了哪个端口,可以在本地绑定套接字后从套接字查询。


2
如果我传入端口0,如何从NetTcpBinding WCF获取套接字? - Ian Ringrose

2

四年后.. 如今我们有了一个解决方案,将 ListenUriMode 设置为 Unique ,正如来自 MSDN 所述。

这里是一个端点配置的小例子:

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

现在的问题是:如果端口是动态的,客户端如何知道它?根据此答案所述,您可以使用WCF DISCOVERY:需要在服务器和客户端上进行一些配置,但它可以很好地工作(唯一的问题是它需要一些时间来获取,默认为20秒,但我可以强制将其设置为5秒)。

2
这是我的做法:先随机选择一个1025-2000的端口(范围任意选择),试图绑定它,如果失败则捕获异常。然后逐个端口向上尝试(port = port % 2000 + 1025),直到回到起点。如果没有端口被绑定,则放弃测试。

每次尝试打开一个端口时,如何停止Windows防火墙自动弹出UK? - Ian Ringrose
嗯,我不太清楚这个防火墙的事情;我的开发机器上没有安装防火墙,因为它在受到防火墙保护的网络内。 - Marcin
Ian,我在开发网络应用程序的计算机上或在我的构建计算机上没有配置防火墙,所以这不是问题。 - Len Holgate

1

当使用随机高端口时,您可能会与其他想要在您的程序之后启动的服务器进程发生冲突。 只需将零用作端口号,让操作系统处理预留(在Unix上的/ etc / services,不知道Windows如何处理)。


抱歉,我只关心 Windows。 - Ian Ringrose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接