尽管IP地址正确,但在WCF中指定了错误的IP地址时出现TCP错误

时间:2013-09-30 18:51:28

标签: c# wcf

我有托管WCF服务的应用程序。 我通过BackgroundWorker

打开连接
private bool isConnected;
private BackgroundWorker asyncWorker = new BackgroundWorker();

    InitializeComponent();        
    asyncWorker.WorkerReportsProgress = true;
    asyncWorker.WorkerSupportsCancellation = true;
    asyncWorker.ProgressChanged += new ProgressChangedEventHandler
                    (bwAsync_ProgressChanged);
    asyncWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (bwAsync_RunWorkerCompleted);
    asyncWorker.DoWork += new DoWorkEventHandler(bwAsync_DoWork);
    btnConnect.BackColor = Color.ForestGreen;

这是我的Connect按钮点击事件:

    private void btnConnect_Click(object sender, EventArgs e)
    {            
        btnConnect.Enabled = false;
        Interface.interfaceNumber = interfaceNumber;
        asyncWorker.RunWorkerAsync();
    }

和DoWork:

private void bwAsync_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker bwAsync = sender as BackgroundWorker;
    try
    {
        if (!isConnected)
        {
            // Returns a list of ipaddress configuration
            IPHostEntry ips = Dns.GetHostEntry(Dns.GetHostName());

            // Get machine ipaddress
            IPAddress _ipAddress = IPAddress.Parse(tbServerIp.Text);

            // Create the url that is needed to specify where the service should be started
            urlService = "net.tcp://" + _ipAddress.ToString() + ":8000/MyService";

            // Instruct the ServiceHost that the type that is used is a ServiceLibrary.service1
            //host = new ServiceHost(typeof(ServiceLibrary.service1));
            ServiceLibrary.service1 serviceInstance = new ServiceLibrary.service1();
            serviceInstance.CapturingEvent += yourServiceInstance_StartCapturingEvent;
            serviceInstance.OnProcessExitedEvent += serviceInstance_OnProcessExitedEvent;
            host = new ServiceHost(serviceInstance);
            host.Opening += new EventHandler(host_Opening);
            host.Opened += new EventHandler(host_Opened);
            host.Closing += new EventHandler(host_Closing);
            host.Closed += new EventHandler(host_Closed);

            // The binding is where we can choose what transport layer we want to use. HTTP, TCP ect.
            NetTcpBinding tcpBinding = new NetTcpBinding();
            tcpBinding.TransactionFlow = false;
            tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
            tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
            tcpBinding.Security.Mode = SecurityMode.None; // <- Very crucial

            // Add a endpoint
            host.AddServiceEndpoint(typeof(ServiceLibrary.IService1), tcpBinding, urlService);

            // A channel to describe the service. Used with the proxy scvutil.exe tool
            ServiceMetadataBehavior metadataBehavior;
            metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (metadataBehavior == null)
            {
                // Create the proxy object that is generated via the svcutil.exe tool
                metadataBehavior = new ServiceMetadataBehavior();
                metadataBehavior.HttpGetUrl = new Uri("http://" + _ipAddress.ToString() + ":8001/MyService");
                metadataBehavior.HttpGetEnabled = true;
                metadataBehavior.ToString();
                host.Description.Behaviors.Add(metadataBehavior);
                urlMeta = metadataBehavior.HttpGetUrl.ToString();
            }

            host.Open();
            isConnected = true;
        }
        else
        {
            if (asyncWorker.IsBusy)
            {
                //bnAsync.Enabled = false;
                this.Invoke((MethodInvoker)delegate { lblStatus.Text = "Cancelling..."; });

                // Notify the worker thread that a cancel has been requested.
                // The cancel will not actually happen until the thread in the
                // DoWork checks the bwAsync.CancellationPending flag, for this
                // reason we set the label to "Cancelling...", because we haven't
                // actually cancelled yet.
                asyncWorker.CancelAsync();
            }

            host.Close();
            isConnected = false;
        }
    }
    catch (Exception ex)
    {
        isConnected = false;
        MessageBox.Show(ex.Message);
        return;
    }
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Lock\Release buttons
}

我的应用程序连接成功,所有工作正常但如果我指定了错误的IP地址我得到TCP错误requested Ip Address is not valid这是好的但如果我修复这个错误的IP地址到正确的IP地址我仍然得到除非重新启动我的应用程序,否则会出现相同 也许我的线程仍在运行,这就是我无法连接的原因?

1 个答案:

答案 0 :(得分:2)

首先不要使用IP地址,除非你只是做localhost开发,这总是一个坏主意,使用DNS名称或托管文件名条目。其次,我假设你的host变量是一个类成员变量(上面没有包含的代码)。打开主机后,它的绑定将在服务器内存中保持活动状态,直到您重新启动标准操作的应用程序。

该代码的另一个问题是,在else bwAsync_DoWork块中,您在单击表单按钮后关闭主机,但是您没有重新绑定/重新打开主机更新的表格数据。请考虑执行以下操作来解决此问题。

  1. 将执行实际主机绑定的代码从bwAsync_DoWork移到自己的方法中。
  2. bwAsync_DoWork的最后调用此方法以确保打开新绑定。
  3. 代码:

    private void bwAsync_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bwAsync = sender as BackgroundWorker;
        if (asyncWorker.IsBusy)
        {
            this.Invoke((MethodInvoker)delegate { lblStatus.Text = "Cancelling..."; });
    
            asyncWorker.CancelAsync();
        }
        else
        {
            if(isConnected)
            {
                host.Close();
                isConnected = false;
            }   
            BindHost();         
        }
    }
    
    
    private void BindHost() 
    {
        ...
        isConnected = true;
    }