【问题标题】:WCF: Net.TCP multiple bindings, same port, different IP AddressesWCF:Net.TCP 多个绑定,相同的端口,不同的 IP 地址
【发布时间】:2009-03-31 21:05:12
【问题描述】:

我遇到了问题。我在 WCF 有点新,所以任何帮助都会非常感激。

这是我的代码:

public static void StartHosts()
    {
        try
        {
            // Create a new host
            ServiceHost host = new ServiceHost(typeof(ServerTasks));

            List<IPAddress> ips = new List<IPAddress>(Dns.GetHostAddresses(Dns.GetHostName()));
            if (IPAddress.Loopback != null)
                ips.Add(IPAddress.Loopback);

            ips.RemoveAll(i => i.AddressFamily != AddressFamily.InterNetwork);

            foreach (var ip in ips)
            {
                string uri = string.Empty;

                // Formulate the uri for this host
                uri = string.Format(
                    "net.tcp://{0}:{1}/ServerTasks",
                    ip.ToString(),
                    ServerSettings.Instance.TCPListeningPort
                );


                // Add the endpoint binding
                host.AddServiceEndpoint(
                    typeof(ServerTasks),
                    new NetTcpBinding(SecurityMode.Transport) { TransferMode = TransferMode.Streamed },
                    uri
                );

            }



            // Add the meta data publishing
            var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
                smb = new ServiceMetadataBehavior();

            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            host.AddServiceEndpoint(
                ServiceMetadataBehavior.MexContractName,
                MetadataExchangeBindings.CreateMexTcpBinding(),
                "net.tcp://localhost/ServerTasks/mex"
            );

            // Run the host
            host.Open();
        }
        catch (Exception exc)
        {
            DebugLogger.WriteException(exc);
        }
    }

一行抛出异常:'host.Open();'

例外是:

System.InvalidOperationException URI 'net.tcp://192.168.1.45:4329/ServerTasks' 的注册已存在。

我要做的是绑定到机器上的所有网络地址,以便客户端应用程序可以从他们看到的任何网络访问服务。当我运行此代码时,它会找到并尝试为大约 5 个不同的 IP(包括 127.0.0.1)设置绑定。

192.168.1.45 是它尝试绑定的第二个 IP。在它引发异常时,我可以看到(使用 netstat)程序已绑定到端口 4329 上列表中的第一个 IP。异常中提到的地址上没有任何绑定到端口 4329 的内容。

对不起,没有太多细节,我想写一个简洁的帖子。如果有人需要更多信息,我很乐意提供。

注意:对于在 foreach 循环中创建的 NetTcpBinding,我尝试将 PortSharingEnabled 设置为 true,但我仍然遇到了同样的错误。

任何帮助或建议将不胜感激!

谢谢

【问题讨论】:

    标签: wcf wcf-binding net.tcp


    【解决方案1】:

    感谢科拉扎提供的信息!

    我已经想出了如何做到这一点。我的做法完全错了。

    我的最终目标是让服务监听机器上每个可用的 IP 地址。尝试单独绑定到每个地址是错误的做法。

    相反,我只需要将服务绑定到机器的主机名(不是“localhost”),WCF 就会自动侦听所有适配器。

    这是更正后的代码:

    public static void StartHosts()
        {
            try
            {
                // Formulate the uri for this host
                string uri = string.Format(
                    "net.tcp://{0}:{1}/ServerTasks",
                    Dns.GetHostName(),
                    ServerSettings.Instance.TCPListeningPort
                );
    
                // Create a new host
                ServiceHost host = new ServiceHost(typeof(ServerTasks), new Uri(uri));
    
                // Add the endpoint binding
                host.AddServiceEndpoint(
                    typeof(ServerTasks),
                    new NetTcpBinding(SecurityMode.Transport) 
                            { 
                                TransferMode = TransferMode.Streamed
                            },
                    uri
                );
    
                // Add the meta data publishing
                var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                    smb = new ServiceMetadataBehavior();
    
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);
    
                host.AddServiceEndpoint(
                    ServiceMetadataBehavior.MexContractName,
                    MetadataExchangeBindings.CreateMexTcpBinding(),
                    "net.tcp://localhost/ServerTasks/mex"
                );
    
                // Run the host
                host.Open();
            }
            catch (Exception exc)
            {
                DebugLogger.WriteException(exc);
            }
        }
    

    【讨论】:

    • 单独绑定到每个 IP 地址是正确的做法,因为否则您的服务器有安全漏洞 - 想象一下(不太可能)当其他服务将自己绑定到特定主机 IP 地址和相同端口的情况,而您的服务是绑定到所有 IP 地址。在这种情况下,冒名顶替者将获得来自客户端的所有连接请求。
    【解决方案2】:

    梅尔,

    虽然我之前从未尝试过这个,但这里有一些我以前听过的示例供大家参考。您可能希望首先创建绑定对象,然后将相同的实例添加到 AddServiceEndpoint 方法,这只是一个想法,所以您不会每次都创建新的绑定,因为我记得在某处读到 netTCPBindings 应该与地址为 1:1 关系(即使您使用不同的地址)。

    我认为您不必担心开放多个端口的端口共享。

    这是您可能希望使用多个端口完成的示例。

    http://www.aspfree.com/c/a/Windows-Scripting/WCF-and-Bindings/2/

    这是在 NetTcpBinding 上使用端口共享的一个很好的示例。

    http://blogs.msdn.com/drnick/archive/2006/08/08/690333.aspx

    -布莱恩

    【讨论】:

      【解决方案3】:

      看来我来晚了:)。但无论如何 - 有一种非常简单的方法可以让 Wcf 监听所有可用的网络接口“net.tcp://0.0.0.0:8523/WCFTestService”。

      【讨论】:

        猜你喜欢
        • 2016-06-21
        • 1970-01-01
        • 2011-03-08
        • 2014-08-06
        • 1970-01-01
        • 1970-01-01
        • 2019-08-11
        • 1970-01-01
        • 2014-02-14
        相关资源
        最近更新 更多