如何获取 WCF 服务正在侦听的端口?

Posted

技术标签:

【中文标题】如何获取 WCF 服务正在侦听的端口?【英文标题】:How can I get the port that a WCF service is listening on? 【发布时间】:2011-04-03 13:35:12 【问题描述】:

我有一个 net.tcp WCF 服务,我希望操作系统选择它应该监听的端口。所以我在 URI 中将端口设置为 0,netstat 确认操作系统选择了 5000 范围内的端口。

如何在服务进程中以代码的形式找到实际选择的端口?

一些代码来展示我的尝试:

Type serviceType = ...;
Uri address = new Uri("net.tcp://0.0.0.0:0/Service/");
ServiceHost serviceHost = new ServiceHost(serviceType, address);
ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(type, binding, "");
int port1 = endPoint.ListenUri.Port; // returns 0
int port2 = serviceHost.BaseAddresses.First().Port; // also returns 0

【问题讨论】:

让服务监听随机端口是很不寻常的 - 你有什么理由要这样做吗? @Cocowalla:该服务是工作进程的一部分,因此一次可以有多个,我们正在寻找不涉及 .NET TCP 端口共享的解决方案。跨度> How can I get the listening address/port of a WCF service? 的可能重复项 【参考方案1】:

不确定这是否会有所帮助,但在 SO 上已经有一个类似的问题: How can I get the listening address/port of a WCF service?

您可能想尝试的已提交答案的相关部分:

foreach (var channelDispatcher in serviceHost.ChannelDispatchers)

            Console.WriteLine(channelDispatcher.Listener.Uri);

所以也许你需要channelDispatcher.Listener.Uri.Port

希望这会有所帮助!

【讨论】:

@D Hoerster:不幸的是,这只是返回了我传入的 URI。感谢指向另一个问题的指针。 @D Hoerster:看起来我们赢了。我还必须设置 endPoint.ListenUriMode = ListenUriMode.Unique;使其正常工作(并禁用绑定上的端口共享)。 你打电话给 Open 了吗?【参考方案2】:

服务启动后,您可以从 Description.Endpoints 集合中获得实际创建的端点的完整描述(这在调用 Open() 之前不起作用)。从这个集合中你可以得到地址。不幸的是,您必须对端口的地址进行字符串解析。

这是我的服务器在每次服务 Open() 后记录的内容。

        serviceHost.Open();

        // Iterate through the endpoints contained in the ServiceDescription 
        System.Text.StringBuilder sb = new System.Text.StringBuilder(string.Format("Active Service Endpoints:0", Environment.NewLine), 128);
        foreach (ServiceEndpoint se in serviceHost.Description.Endpoints)
        
            sb.Append(String.Format("Endpoint:0", Environment.NewLine));
            sb.Append(String.Format("\tAddress: 01", se.Address, Environment.NewLine));
            sb.Append(String.Format("\tBinding: 01", se.Binding, Environment.NewLine));
            sb.Append(String.Format("\tContract: 01", se.Contract.Name, Environment.NewLine));
            foreach (IEndpointBehavior behavior in se.Behaviors)
            
                sb.Append(String.Format("Behavior: 01", behavior, Environment.NewLine));
            
        

        Console.WriteLine(sb.ToString());

【讨论】:

【参考方案3】:

作为替代方案,您可以找到一个免费端口供 WCF 自己使用:

private int FindPort()

    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);

    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    
         socket.Bind(endPoint);
         IPEndPoint local = (IPEndPoint)socket.LocalEndPoint;
         return local.Port;
    

来自here的代码。

【讨论】:

这不安全。其他人可以在处理套接字之后但在打开 ServiceHost 之前抢夺端口。所以这个方法可能会偶尔失败。

以上是关于如何获取 WCF 服务正在侦听的端口?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定正在侦听端口 80 的服务器

如何解决 C# IIS 托管的 WCF NET TCP 服务超时问题

如何获取进程监听的端口?

如何更改 HSQLDB 服务器侦听的端口

使用 IPC 如何告诉客户端服务器正在侦听哪个端口?

boost.asio 如何发现我的服务器应用程序正在侦听哪个端口?