Проблема преобразование IPv6 в IPv4
Вопрос
У меня есть какой -то код в приложении ASP.NET, который нуждается в получении адреса IPv4 клиентского компьютера (пользователи - все в нашей собственной сети). Недавно мы обновили сервер, который приложение работает на сервере Windows 2008. Теперь код request.userhostaddress возвращает IPv4, когда клиент находится на более старой ОС и IPv6, когда они находятся в более новой ОС (Vista и выше). Таким образом, функция, которая полагается на это, работает для некоторых клиентов, а не для других.
Я добавил код, который должен преобразовать из IPv6 в IPv4, чтобы попытаться решить эту проблему. Это из этого онлайн -учебника: http://www.4guysfromrolla.com/articles/071807-1.aspx . Я использую dsn.gethostaddress, а затем зацикливаться на возвращении IPS в поисках той, которая является «интернет -работой»
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;
Проблема в том, что это не работает для меня. Клиенты, подключающиеся из IPv4, продолжают возвращать правильный IP4 IP4 клиентского компьютера, но клиенты, подключающиеся из Vista и Windows 7, возвращает IPv4 IP - Сервер Машина, а не клиентский компьютер.
Решение
Простой ответ: отключить IPv6 на сервере или удалить адрес IPv6 сервера из записи DNS.
Не существует волшебного IPv4 <--> IPv6 преобразователя. Они совершенно разные протоколы, а адреса в одном не переводится на другой. Если вы хотите надежно получить адрес IPv4 клиента, вам необходимо убедиться, что клиент подключается к IPv4.
Другие советы
Я также скопировал пример кода, и коллега отметил, что это явно было глюком. Эта строка использует имя хоста сервера, следовательно, неверный результат:
foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
Я исправил код в своем проекте следующим образом:
/// <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;
}
Приведенный выше код работает в ASP.NET 2.0 в Windows 7/Server 2008. Надеюсь, это поможет.
Если вы используете Framework .net 4.5, то есть метод, который предоставляет для преобразования IP6 в IP4
public IPAddress MapToIPv4()
Вы можете найти детали здесь