2010-01-08 4 views
9

Bezug zu How to get the IP address of a WCF remote endpoint?IPv4 Remote-Adresse in WCF

ich diesen Code bin mit dem Remote-IP-Adresse abzurufen, wenn ein Workflow-Methode aufgerufen wird:

private static string GetRemoteIP() 
{ 
    var oc = OperationContext.Current; 
    var mp = oc.IncomingMessageProperties; 
    var remp = mp[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; 

    return remp == null ? "(unknown)" : remp.Address; 
} 

jedoch die Adresse ich zurück ist „: : 1 ". Ich möchte nicht die IPv6-Adresse, ich möchte die IPv4-Adresse (127.0.0.1) - eine Möglichkeit, dies zu erzwingen?

Antwort

4

Nein, das glaube ich nicht. Sie lesen grundsätzlich nur eine Eigenschaft aus, die zum Zeitpunkt des Anrufs vom Client festgelegt wurde. Ihre einzige Option wäre, den Client (über einige Konfigurationen) anzuweisen, zu jeder Zeit IPv4 anstelle von IPv6 zu verwenden (d. H. IPv6 alle zusammen auszuschalten).

Mir ist keine WCF-Einstellung bekannt, um dies zu erzwingen - Sie müssten in den Netzwerk-Stack einsteigen und sehen, ob es eine Möglichkeit gibt, IPv4-Adressen anstelle von IPv6 zu verwenden.

2

ist hier eine Abhilfe: (Sie die Werte in einer Hash-Tabelle speichern können mehrere DNS-Operationen zu vermeiden)

static string GetClientIP() 
    { 
     var context = OperationContext.Current; 
     var mp = context.IncomingMessageProperties; 
     var propName = RemoteEndpointMessageProperty.Name; 
     var prop = (RemoteEndpointMessageProperty) mp[propName]; 
     string remoteIP = prop.Address; 

     if(remoteIP.IndexOf(":") > -1) 
     { 
      IPAddress[] addresses = Dns.GetHostAddresses(remoteIP); 
      for (int i = 0; i < addresses.Length; i++) 
      { 
       if(addresses[i].ToString().IndexOf(".")>-1) 
        return addresses[i].ToString(); 
      } 
      return remoteIP; 
     } 
     else 
     { 
      return remoteIP; 
     } 
    } 
+0

IndexOf gibt immer ein Ergebnis zurück, das> = -1 ist, so dass das 'if' immer den' else'-Zweig auswählt. –

+0

Sollte die erste "if" -Anweisung nicht gelesen werden: if (remoteIP.IndexOf (":")> -1)? –

3

Du siehst :: 1, weil man durch die Auflösung des Namens in den Dienst der Sie eine Verbindung "localhost" anstelle von "127.0.0.1". Moderne Windows-Versionen, für die der IPv6-Stapel aktiviert ist, verwenden zuerst IPv6.

Sie können den IPv6-Stack deaktivieren, aber das ist ungefähr das gleiche wie wenn Sie sich wie ein Strauß machen und den Kopf in den Sand stecken. IPv6 ist hier, und die Leute nutzen es in ihren Netzwerken, daher sollte Ihre Anwendung darauf vorbereitet sein, sie zu unterstützen.

2

Die von Murat vorgeschlagene Problemumgehung funktioniert nicht. Die MSDN sagt - wenn Sie die IP-Adresse an die GetHostAddresses-Methode übergeben, wird diese Adresse in einem Array ohne Abfrage der DNS zurückgegeben. Damit es funktioniert, müssen Sie zuerst den Hostnamen mithilfe der GetHostEntry-Methode abfragen. Verwenden Sie dann den Hostnamen GetHostAddresses. Jedoch kann sogar die GetHostEntry die Liste der Adressen haben, die für Sie genug sind.

0

Sie könnten AddressFamily.InterNetwork == address.AddressFamily und AddressFamily.InterNetworkV6 als Test verwenden, anstatt nach ":" oder "." in den Adressen-Strings.