Получить локальный IP-адрес
в интернете есть несколько мест, которые показывают вам, как получить IP-адрес. И многие из них выглядят так:
String strHostName = string.Empty;
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
}
Console.ReadLine();
в этом примере я получаю несколько IP-адресов, но меня интересует только тот, который маршрутизатор назначает компьютеру, на котором запущена программа: IP, который я бы дал кому-то, если он хочет получить доступ к общей папке на моем компьютере, например.
Если я не подключен к сети и я подключен к интернет непосредственно через модем без маршрутизатора, тогда я хотел бы получить ошибку. Как я могу увидеть, подключен ли мой компьютер к сети С C#, и если это то, чтобы получить IP-адрес LAN.
21 ответов
чтобы получить локальный Ip-адрес:
public static string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
чтобы проверить, подключены вы или нет:
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
более точный путь когда multi ip-адреса доступные на локальной машине. Connect
сокет UDP и прочитайте его локальную конечную точку:
string localIP;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
localIP = endPoint.Address.ToString();
}
Connect
на сокете UDP имеет следующий эффект: он устанавливает назначение для Send
/Recv
, отбрасывает все пакеты с других адресов и - что мы используем-передает сокет в состояние "подключено", настраивает его соответствующие поля. Это включает в себя проверку существования маршрута до места назначения в соответствии с таблицей маршрутизации системы и установкой локальной конечной точки соответственно. Последняя часть кажется недокументированной официально, но она выглядит как неотъемлемая черта Berkeley sockets API (побочный эффект состояния UDP "подключен"), который надежно работает в обоих окнах и Linux в разных версиях и дистрибутивах.
Итак, этот способ даст локальный адрес, который будет использоваться для подключения к указанному удаленному узлу. Нет реальной связи установлено, следовательно, указанный удаленный IP может быть недоступна.
рефакторинг кода Mrcheif для использования Linq(т. е. .Чистая 3.0+). .
private IPAddress LocalIPAddress()
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
return null;
}
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
return host
.AddressList
.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
}
:)
Я знаю, что это может быть пинать мертвую лошадь, но, возможно, это может помочь кому-то. Я искал повсюду способ найти свой локальный IP-адрес, но везде, где я нахожу его, говорит использовать:
Dns.GetHostEntry(Dns.GetHostName());
мне это совсем не нравится, потому что он просто получает все адреса, назначенные вашему компьютеру. Если у вас есть несколько сетевых интерфейсов (что почти все компьютеры делают сейчас), вы понятия не имеете, какой адрес идет с каким сетевым интерфейсом. Проведя кучу исследований Я создал функцию для использования класса NetworkInterface и извлечения из него информации. Таким образом, я могу сказать, какой это тип интерфейса (Ethernet, wireless, loopback, tunnel и т. д.), является ли он активным или нет, и SOOO намного больше.
public string GetLocalIPv4(NetworkInterfaceType _type)
{
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
}
}
return output;
}
теперь, чтобы получить IPv4-адрес вашего сетевого интерфейса Ethernet:
GetLocalIPv4(NetworkInterfaceType.Ethernet);
или ваш беспроводной интерфейс:
GetLocalIPv4(NetworkInterfaceType.Wireless80211);
если вы пытаетесь получить IPv4-адрес для беспроводного интерфейса, но ваш компьютер не если установлена беспроводная карта, она просто вернет пустую строку. То же самое с интерфейсом Ethernet.
надеюсь, это поможет кому-то! :-)
EDIT:
было указано (спасибо @NasBanov), что, хотя эта функция идет о извлечении IP-адреса намного лучше, чем использование Dns.GetHostEntry(Dns.GetHostName())
это не очень хорошо поддерживать несколько интерфейсов одного типа или нескольких IP-адресов на одном интерфейсе. Это будет только возвращает один IP-адрес, когда может быть назначено несколько адресов. Чтобы вернуть все эти назначенные адреса, вы можете просто манипулировать исходной функцией, чтобы всегда возвращать массив вместо одной строки. Например:
public static string[] GetAllLocalIPv4(NetworkInterfaceType _type)
{
List<string> ipAddrList = new List<string>();
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
ipAddrList.Add(ip.Address.ToString());
}
}
}
}
return ipAddrList.ToArray();
}
теперь эта функция вернет все назначенные адреса для определенного типа интерфейса. Теперь, чтобы получить только одну строку, вы можете использовать .FirstOrDefault()
extension для возврата первого элемента в массиве или, если он пуст, вернуть пустой строка.
GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
вот модифицированная версия (от compman2408), которая работала для меня:
internal static string GetLocalIPv4(NetworkInterfaceType _type)
{
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties adapterProperties = item.GetIPProperties();
if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
{
foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
}
}
}
return output;
}
изменение: я получаю IP-адрес от адаптера, которому назначен IP-адрес шлюза.
Это лучший код, который я нашел, чтобы получить текущий IP, избегая получить VMware host или другой недопустимый IP-адрес.
public string GetLocalIpAddress()
{
UnicastIPAddressInformation mostSuitableIp = null;
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var network in networkInterfaces)
{
if (network.OperationalStatus != OperationalStatus.Up)
continue;
var properties = network.GetIPProperties();
if (properties.GatewayAddresses.Count == 0)
continue;
foreach (var address in properties.UnicastAddresses)
{
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
if (IPAddress.IsLoopback(address.Address))
continue;
if (!address.IsDnsEligible)
{
if (mostSuitableIp == null)
mostSuitableIp = address;
continue;
}
// The best IP is the IP got from DHCP server
if (address.PrefixOrigin != PrefixOrigin.Dhcp)
{
if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
mostSuitableIp = address;
continue;
}
return address.Address.ToString();
}
}
return mostSuitableIp != null
? mostSuitableIp.Address.ToString()
: "";
}
Я думаю, что использовать LinQ проще:
Dns.GetHostEntry(Dns.GetHostName())
.AddressList.First(
f => f.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
.ToString()
@mrcheif я нашел этот ответ сегодня, и это было очень полезно, хотя он вернул неправильный IP (не из-за кода не работает), но он дал неправильный IP-адрес в интернете, когда у вас есть такие вещи, как himachi работает.
public static string localIPAddress()
{
IPHostEntry host;
string localIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
localIP = ip.ToString();
string[] temp = localIP.Split('.');
if (ip.AddressFamily == AddressFamily.InterNetwork && temp[0] == "192")
{
break;
}
else
{
localIP = null;
}
}
return localIP;
}
для смеха, подумал, что я попытаюсь получить один оператор LINQ, используя новый оператор c# 6 null-conditional. Выглядит довольно сумасшедшим и, вероятно, ужасно неэффективным, но он работает.
private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
// Bastardized from: http://stackoverflow.com/a/28621250/2685650.
return NetworkInterface
.GetAllNetworkInterfaces()
.FirstOrDefault(ni =>
ni.NetworkInterfaceType == type
&& ni.OperationalStatus == OperationalStatus.Up
&& ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null
&& ni.GetIPProperties().UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) != null
)
?.GetIPProperties()
.UnicastAddresses
.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
?.Address
?.ToString()
?? string.Empty;
}
логика вежливость Gerardo H
(и по ссылке compman2408
).
предварительные условия: вы должны добавить систему.Данные.Ссылка Linq и ссылаться на нее
using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));
другой способ получить IP с помощью выражения linq:
public static List<string> GetAllLocalIPv4(NetworkInterfaceType type)
{
return NetworkInterface.GetAllNetworkInterfaces()
.Where(x => x.NetworkInterfaceType == type && x.OperationalStatus == OperationalStatus.Up)
.SelectMany(x => x.GetIPProperties().UnicastAddresses)
.Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address.ToString()).ToList();
}
string str="";
System.Net.Dns.GetHostName();
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(str);
IPAddress[] addr = ipEntry.AddressList;
string IP="Your Ip Address Is :->"+ addr[addr.Length - 1].ToString();
имейте в виду, что в общем случае вы можете иметь несколько переводов NAT и несколько dns-серверов, каждый из которых работает на разных уровнях перевода NAT.
Что если вы имеете ранг NAT несущей, и хотите связывать с другими клиентами такой же несущей? В общем случае вы никогда не знаете наверняка, потому что вы можете появиться с разными именами хостов при каждом переводе NAT.
просто обновленная версия моей, используя LINQ:
/// <summary>
/// Gets the local Ipv4.
/// </summary>
/// <returns>The local Ipv4.</returns>
/// <param name="networkInterfaceType">Network interface type.</param>
IPAddress GetLocalIPv4(NetworkInterfaceType networkInterfaceType)
{
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => i.NetworkInterfaceType == networkInterfaceType && i.OperationalStatus == OperationalStatus.Up);
foreach (NetworkInterface networkInterface in networkInterfaces)
{
var adapterProperties = networkInterface.GetIPProperties();
if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
{
foreach (UnicastIPAddressInformation ip in networkInterface.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
return ip.Address;
}
}
}
}
return null;
}
устаревшие ушел, это работает для меня
public static IPAddress GetIPAddress()
{
IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address =>
address.AddressFamily == AddressFamily.InterNetwork).First();
return ip;
}
обновление ответа Mrchief с помощью Linq, у нас будет:
public static IPAddress GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
return ipAddress;
}
Я также боролся с получением правильного IP-адреса.
Я пробовал различные решения здесь, но ни один не дал мне желаемого эффекта. Почти все предоставленные условные тесты не привели к использованию адреса.
Это то, что сработало для меня, надеюсь, это поможет...
var firstAddress = (from address in NetworkInterface.GetAllNetworkInterfaces().Select(x => x.GetIPProperties()).SelectMany(x => x.UnicastAddresses).Select(x => x.Address)
where !IPAddress.IsLoopback(address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
select address).FirstOrDefault();
Console.WriteLine(firstAddress);
протестировано с одной или несколькими LAN-картами и виртуальными машинами
public static string DisplayIPAddresses()
{
string returnAddress = String.Empty;
// Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface network in networkInterfaces)
{
// Read the IP configuration for each network
IPInterfaceProperties properties = network.GetIPProperties();
if (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
network.OperationalStatus == OperationalStatus.Up &&
!network.Description.ToLower().Contains("virtual") &&
!network.Description.ToLower().Contains("pseudo"))
{
// Each network interface may have multiple IP addresses
foreach (IPAddressInformation address in properties.UnicastAddresses)
{
// We're only interested in IPv4 addresses for now
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
// Ignore loopback addresses (e.g., 127.0.0.1)
if (IPAddress.IsLoopback(address.Address))
continue;
returnAddress = address.Address.ToString();
Console.WriteLine(address.Address.ToString() + " (" + network.Name + " - " + network.Description + ")");
}
}
}
return returnAddress;
}
Если у вас есть виртуальные машины или дополнительные сетевые карты, в addresslist могут быть другие значения. Мое предложение-проверить записи addresslist и распечатать, что подходит. В моем случае запись 3 была IPv4-адресом моей машины
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[3];
string ip = ipAddr.ToString();
Не забудьте добавить using System.Net;
здесь приходит полнофункциональный и твердый 1-лайнер для локального IP-адреса-вопрос. Сделано с параллельным языком исполнения Dyalog APL. Интересно, что этот небольшой фрагмент кода поддерживает 0, 1 или несколько адаптеров IPv4 - результат будет просто массив длиной 0, 1 или n вложенных текстовых векторов.
в основном для путаницы, я думаю :-)
#.Dns.(a.AddressFamily.(⎕THIS=InterNetwork)/a←(GetHostEntry GetHostName).AddressList).ToString
Returns (для этого компьютера): 192.168.0.100 (