2010-01-11 12 views
8

J'ai du code dans une application asp.net qui nécessite l'adresse ipv4 de l'ordinateur client (les utilisateurs sont tous sur notre propre réseau). Récemment, nous avons mis à jour le serveur sur lequel l'application fonctionne sur le serveur Windows 2008. Maintenant le code Request.UserHostAddress renvoie l'ipv4 quand le client est sur un OS plus ancien et ipv6 quand ils sont sur un OS plus récent (Vista et supérieur). Donc, la fonctionnalité qui repose sur cela fonctionne pour certains clients et pas d'autres.Problème Conversion d'ipv6 en ipv4

J'ai ajouté du code supposé convertir d'ipv6 en ipv4 pour essayer de résoudre ce problème. Il est de ce tutoriel en ligne: http://www.4guysfromrolla.com/articles/071807-1.aspx .I'm en utilisant dsn.GetHostAddress puis en boucle à travers les adresses IP à la recherche d'un ont retourné qui est « InterNetwork »

foreach (IPAddress IPA in Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress)) 
{ 
    if (IPA.AddressFamily.ToString() == "InterNetwork") 
    { 
     IP4Address = IPA.ToString(); 
     break; 
    } 
} 

if (IP4Address != String.Empty) 
{ 
    return IP4Address; 
} 


foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName())) 
{ 
    if (IPA.AddressFamily.ToString() == "InterNetwork") 
    { 
     IP4Address = IPA.ToString(); 
     break; 
    } 
} 

return IP4Address; 

Le problème est que cela ne fonctionne pas pour moi. Les clients se connectant depuis ipv4 continuent de renvoyer l'adresse IP ipv4 correcte de l'ordinateur client, mais les clients se connectant à partir de Vista et Windows 7 retournent l'IP ipv4 de la machine SERVER et non l'ordinateur client.

+8

J'ai vu cet exemple de code répété sur de nombreux blogs. Je suis étonné car c'est tellement faux .. partie 1, obtenir l'adresse IP du client. Si cela échoue, renvoyez l'adresse IP du serveur. wtf?!? –

+4

Oui, juste trouvé ce même exemple ici: http://www.4guysfromrolla.com/articles/071807-1.aspx. Si rien d'autre, en utilisant 'ToString()' pour vérifier l'égalité enum ressemble à ce qu'il a été écrit par un débutant .NET total. – Groo

Répondre

7

Réponse simple: Désactivez IPV6 sur le serveur ou supprimez l'adresse IPV6 du serveur de l'entrée DNS.

Il n'y a pas de magique IPV4 < -> Convertisseur IPV6. Ce sont des protocoles complètement différents, et les adresses dans l'un ne se traduisent pas par l'autre. Si vous souhaitez récupérer de manière fiable l'adresse IPV4 du client, vous devez vous assurer que le client se connecte sur IPV4.

+6

Et bien sûr le conseil évident: IPv6 arrive, préparez votre logiciel pour le traiter correctement. S'appuyer sur les adresses IPv4 va vous faire du mal. –

1

si vous utilisez Net Framework 4.5 puis il y a une méthode FOURNISSEZ convertir IP6 à IP4

public IPAddress MapToIPv4() 

Vous pouvez trouver les détails here

+4

Cette méthode n'a de sens que pour les adresses IPv6 obtenues en mappant les adresses IPv4 vers v6 en premier lieu. Comme le dit Jesse Weigert, il n'y a pas de convertisseur magique v6 -> v4. – AakashM

6

J'avais aussi copié le code exemple et un collègue a souligné que c'était évidemment buggy. Cette ligne utilise le nom d'hôte du serveur, d'où le résultat incorrect:

foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName())) 

J'ai corrigé le code dans mon projet comme suit:

/// <summary> 
/// Returns the IPv4 address of the specified host name or IP address. 
/// </summary> 
/// <param name="sHostNameOrAddress">The host name or IP address to resolve.</param> 
/// <returns>The first IPv4 address associated with the specified host name, or null.</returns> 
public static string GetIPv4Address(string sHostNameOrAddress) 
{ 
    try 
    { 
    // Get the list of IP addresses for the specified host 
    IPAddress[] aIPHostAddresses = Dns.GetHostAddresses(sHostNameOrAddress); 

    // First try to find a real IPV4 address in the list 
    foreach (IPAddress ipHost in aIPHostAddresses) 
     if (ipHost.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
     return ipHost.ToString(); 

    // If that didn't work, try to lookup the IPV4 addresses for IPV6 addresses in the list 
    foreach (IPAddress ipHost in aIPHostAddresses) 
    if (ipHost.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) 
     { 
     IPHostEntry ihe = Dns.GetHostEntry(ipHost); 
     foreach (IPAddress ipEntry in ihe.AddressList) 
      if (ipEntry.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
      return ipEntry.ToString(); 
     } 
    } 
    catch (Exception ex) 
    { 
    System.Diagnostics.Trace.WriteLine(ex); 
    } 
    return null; 
} 

Le code ci-dessus fonctionne dans ASP.Net 2.0 sur Windows 7/Server 2008. Espérons que cela aide.

+0

pas un ventilateur de supports? :) – Evorlor