配置和启动WCF服务的问题

时间:2011-07-11 11:41:39

标签: c# .net wcf configuration

配置和启动WCF服务时遇到问题。 在我的应用程序中有一个启动服务的方法。像这样的东西

void Start(string protocol, string address, string port)
{
    host = new ServiceHost(_myService,
        new Uri(String.Format("{0}://{1}{2}/Sample", protocol, address, port)));
    //...Some configuration (bindings, behaviors, etc.)
    host.Open();
}

让我的电脑拥有IP 192.168.0.1。当我使用值'192.168.0.2'传递'address'参数时发生错误

"A TCP error (10049: The requested address is not valid in its context.)
 occurred while listening on IP Endpoint=192.168.0.2:1234"

这是正确的,因为它不是我的IP。但在那之后,如果我传递正确的值(我的真实IP),我得到关于IP 192.168.0.2的相同错误!因此,如果不重新启动应用程序,我无法重新配置和重新启动服务器。

为什么会这样?我该如何避免这种行为?

2 个答案:

答案 0 :(得分:0)

我无法从您的问题中看到您如何添加正确的端点,但我怀疑您正在尝试修改端点地址。使用WCF服务,在调用

后无法更改端点地址
host.Open();

因为此时该服务(如果您没有错误)并接受来自指定地址和端口号的客户端的请求。

如果您希望在新地址托管服务,则需要使用正确的端点地址创建新的ServiceHost对象(并处置旧的端点地址)。

编辑:

在使用您发布的示例解决方案之后,我找到了解决问题的方法。我认为出现了问题,因为您在两次尝试中使用相同的端口号(在我下载的示例解决方案中,您没有指定此项,因此端口默认为808)。如果您按如下方式更改代码,以便在第二次尝试的基地址中指定不同的端口号,则您遇到的错误将消失:

 try
        {
            var host2 = CreateServiceHost("localhost:5432", serviceImpl);

            Console.WriteLine("#2, config: " + host2.BaseAddresses.First().ToString());

            host2.Open();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

WCF本身下面似乎有一些错误,可能是在套接字级别上,在第一次错误的IP错误之后,端口仍然不可用。

我做了一个快速谷歌和found this article,有人在关闭套接字后遇到延迟重用端口的问题。如果您总是需要使用相同的端口号,也许您可​​以等待一段时间让端口再次释放,然后再尝试创建服务主机。

答案 1 :(得分:0)

看起来WCF在类ExclusiveTCPTransportManager中缓存套接字对象。

这对我来说似乎是一个很好的解决方案:

public static class WCFBugWorkaround
{
    public static bool IsConnectionPossible(this ServiceHost host)
    {
        try
        {
            foreach (var baseAddress in host.BaseAddresses)
            {
                IPAddress[] ipAddresses = Dns.GetHostAddresses(baseAddress.DnsSafeHost);
                IPAddress ipAddr = ipAddresses.Where(e => e.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();

                if (ipAddr == null)
                {
                    return false;
                }

                using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    System.Net.IPEndPoint localEP = new IPEndPoint(ipAddr, baseAddress.Port);
                    s.Bind(localEP);
                }
            }
        }
        catch (Exception ex)
        {
            return false;
        }

        return true;
    }
}

ServiceHost host = ...;

...

if (host.IsConnectionPossible())
{
    host.Open();
}

感谢Francheska向我展示正确的方向:)