2009-03-31 11 views
9

Ich habe ein Problem festgestellt. Ich bin ein wenig neu bei WCF, so würde jede Hilfe sehr appreciated werden.WCF: Net.TCP mehrere Bindungen, gleichen Port, verschiedene IP-Adressen

Hier ist mein Code:

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); 
     } 
    } 

Eine Ausnahme auf der Linie geworfen wird: 'host.Open();'

Die Ausnahme ist:

System.InvalidOperationException bereits eine Registrierung für 'net.tcp: //192.168.1.45: 4329/Servertasks' URI existiert.

Ich versuche, an alle Netzwerkadressen auf dem Computer zu binden, damit die Clientanwendungen den Dienst von dem Netzwerk aus erreichen können, auf dem sie angezeigt werden. Wenn ich diesen Code ausführe, findet er und versucht, eine Bindung für ungefähr 5 verschiedene IPs einzurichten, einschließlich 127.0.0.1.

192.168.1.45 ist die zweite IP, an die es zu binden versucht. An dem Punkt, an dem die Ausnahme ausgelöst wird, kann ich (unter Verwendung von netstat) sehen, dass das Programm an die erste IP in der Liste an Port 4329 gebunden hat. Es ist nichts an Port 4329 an der in der Ausnahme erwähnten Adresse gebunden.

Sorry, es gibt nicht viele Details, ich wollte einen prägnanten Beitrag geben. Wenn jemand mehr Informationen benötigt, werde ich es gerne liefern.

Hinweis: Ich habe versucht, PortSharingEnabled für die NetTcpBinding, die innerhalb der Foreach-Schleife erstellt wird, auf True zu setzen, aber ich habe immer noch den gleichen Fehler festgestellt.

Jede Hilfe oder Beratung wäre sehr appreciated!

Dank

Antwort

10

Danke für die Info Corazza!

Ich habe herausgefunden, wie dies zu erreichen ist. Ich ging diesen ganzen falschen Weg.

Mein ultimatives Ziel war es, den Service auf jede IP-Adresse zu hören, die auf dem Gerät verfügbar ist. Der Versuch, an jede Adresse einzeln zu binden, ist der falsche Weg.

Stattdessen musste ich nur den Dienst an den Host des Host-Namens (nicht 'localhost') binden, und WCF überwacht automatisch alle Adapter.

Hier ist der korrigierte Code:

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); 
     } 
    } 
+1

Bindung an jede IP-Adresse einzeln ist richtig zu tun, weil sonst Ihr Server Sicherheitslücke hat - vorstellen (unwahrscheinlich) Situation, wenn anderer Dienst sich an bestimmte Host-IP-Adresse und den gleichen Port bindet, während Ihr Dienst an alle IP-Adressen gebunden ist . In diesem Fall erhält der Betrüger alle Verbindungsanforderungen von Clients, die an diese IP-Adresse weitergeleitet werden. – AlexT

2

Mel,

Während ich habe das noch nie selbst ausprobiert, hier einige Beispiele zu sehen, dass ich zuvor gehört habe. Vielleicht möchten Sie zuerst Ihr Bindungsobjekt erstellen und dann der AddServiceEndpoint-Methode dieselbe Instanz hinzufügen, nur ein Gedanke, damit Sie nicht jedes Mal neue Bindungen erstellen, wenn ich mich erinnere, dass netTCPBindings eine 1: 1-Beziehung mit der Adresse sein sollte (obwohl Sie verschiedene Adressen verwenden).

Ich glaube nicht, dass Sie sich Sorgen über Port-Sharing machen müssen, da Sie mehrere Ports öffnen.

Hier ist ein Beispiel, was Sie mit mehreren Ports erreichen möchten.

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

Hier ist ein gutes Beispiel für die auf dem NetTcpBinding mit portsharing.

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

-Bryan

1

sieht aus wie ich etwas spät dran :) bin. Aber trotzdem - es gibt eine recht einfache Möglichkeit, Wcf alle verfügbaren Netzwerkschnittstellen "net.tcp: /0.0.0.0: 8523/WCFTestService" anzuhören.

Verwandte Themen