Obter endereço IP local

301

Na internet, existem vários locais que mostram como obter um endereço IP. E muitos deles se parecem com este exemplo:

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

Neste exemplo, obtenho vários endereços IP, mas só estou interessado em obter o que o roteador atribui ao computador executando o programa: o IP que eu daria a alguém se ele desejar acessar uma pasta compartilhada no meu computador para instância.

Se eu não estiver conectado a uma rede e estiver conectado à Internet diretamente através de um modem sem roteador, gostaria de receber um erro. Como posso ver se meu computador está conectado a uma rede com C # e se é para obter o endereço IP da LAN.

Tono Nam
fonte
If I am not connected to a network and I am connected to the internet Esta afirmação parece contraditória. Você está tentando descobrir se o seu computador está conectado a uma LAN privada ou à Internet?
21711 Andy
4
Apenas como aviso: um computador pode ter mais de uma interface IP, por exemplo, uma LAN e Wi-Fi. Se você vincular um serviço a uma determinada peça de hardware (por exemplo, a LAN), precisará do IP da LAN. A maioria dos exemplos a seguir retornará o endereço IP "primeiro" ou "último" encontrado. Se você tiver mais de 2 endereços IP, seu programa poderá funcionar 50% do tempo, dependendo da ordem aleatória em que o SO retornar os endereços IP.
Mark Lakata
@ MarkLakata Pensei no mesmo problema. A função na minha resposta abaixo irá lidar com isso. Você pode especificar de que tipo de interface de rede você deseja o endereço IP.
compman2408
3
Apenas FTR, se você pesquisar aqui no Unity3D, é Network.player.ipAddress em sua API
Fattie
@MarkLakata, estritamente falando, o IP "primeiro" ou "último" é o IP "correto", pois o navegador pode usar qualquer IP disponível. Provavelmente, uma boa correção deve ser retornar todos os IP associados à máquina.
UncaAlby

Respostas:

457

Para obter o endereço IP local:

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

Para verificar se você está conectado ou não:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

Mrchief
fonte
29
não vai funcionar se você usar coisas como caixa de vm virtual, genymotion, etc.
PauLEffect
5
Concorde com PaulEffect. Não apenas esse método é ruim para várias placas de rede, mas também não diferencia os endereços IP v6 e IP v4.
Max
16
@ John AddressFamily.InterNetwork é v4 IP e AddressFamily.InterNetworkV6 é IP v6
Leonardo Xavier
Estou usando Geraldo H Resposta, mas se alguém está usando isso, você pode querer remover todos os ips que termina com 1, então ele irá remover auto-retorno e VirtualBox / vmware ips padrão
Leonardo Xavier
6
Parece que você está usando o VMWare ou outro software de virtualização. O OP não pediu isso, então acho que a votação por causa disso é um pouco dura. Se você possui VMWare ou várias NICs, algumas das outras respostas já fornecem pistas para isso.
Mrchief
218

Existe uma maneira mais precisa quando existem endereços IP múltiplos disponíveis na máquina local. Connectum soquete UDP e leia seu terminal local:

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

Connectem um soquete UDP tem o seguinte efeito: define o destino para Send/ Recv, descarta todos os pacotes de outros endereços e - que é o que usamos - transfere o soquete para o estado "conectado", define seus campos apropriados. Isso inclui verificar a existência da rota para o destino de acordo com a tabela de roteamento do sistema e definir o terminal local de acordo. A última parte parece não estar oficialmente documentada, mas parece uma característica integrante da API de soquetes de Berkeley (um efeito colateral do estado "conectado" do UDP) que funciona de maneira confiável no Windows e Linux em versões e distribuições.

Portanto, esse método fornecerá o endereço local que seria usado para conectar-se ao host remoto especificado. Não há uma conexão real estabelecida; portanto, o ip remoto especificado pode estar inacessível.

Mr.Wang da porta ao lado
fonte
4
Esta é a melhor solução que funcionou para as minhas necessidades. Na minha situação, tenho muitas placas de rede e algumas conexões sem fio. Eu precisava obter o endereço IP preferido, dependendo da conexão ativada.
David
10
Sem uma conexão de rede - você não tem nenhum endereço IP. Portanto, o código ainda é válido, embora seja prudente adicionar uma tentativa trycatch para lidar com essa situação e retornar algo como "127.0.0.1" se uma SocketException fosse lançada.
Russ
2
@PatrickSteele, sim, ele retorna o endereço IP de saída preferido para o destino específico. se você deseja obter o seu endereço IP da LAN, tente indicar o alvo a ser algum ip da sua LAN
Mr.Wang from Next Door
2
Esse método funciona em um Mac com núcleo dotnet, enquanto a resposta aceita atualmente não.
Pellet
9
Esta solução funciona cerca de quatro vezes mais rápido que a resposta aceita (por Mrchief). Esta deve ser a resposta real
Kamarey
115

Refatorando o código de Mrcheif para alavancar o Linq (ou seja, .Net 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);
}

:)

Pure.Krome
fonte
Eu tenho alguns endereços IP como "Rede Inter" e esta solução realmente funciona e devolve o caminho certo. O outro de Mrchief me dá o último. Então, na verdade, este deve ser o caminho certo;)
Keenora Fluffball
26
@KeenoraFluffball - este fornece o primeiro, enquanto este fornece o último (ou vice-versa, depende de como a lista é construída). De qualquer maneira, nenhum dos dois está certo - se houver mais de um endereço IP fornecido, você precisará saber qual rede está usando. Adivinhar tomando a primeira ou a última não é a solução correta.
gbjbaanb 4/09/2013
Pode querer incluir também AddressFamily.InterNetworkV6 #
joelsand
o retorno de null se a rede não estiver disponível não será útil se você também tiver que lidar com PCs independentes. Substituí-o por "return IPAddress.Loopback;" que corresponde ao número IP especial 127.0.0.1.
Christian
109

Eu sei que isso pode estar chutando um cavalo morto, mas talvez isso possa ajudar alguém. Procurei em todo o lugar uma maneira de encontrar meu endereço IP local, mas em todos os lugares que encontro diz para usar:

Dns.GetHostEntry(Dns.GetHostName());

Não gosto nada disso, porque apenas obtém todos os endereços atribuídos ao seu computador. Se você possui várias interfaces de rede (o que praticamente todos os computadores têm atualmente), você não tem idéia de qual endereço combina com qual interface de rede. Depois de fazer várias pesquisas, criei uma função para usar a classe NetworkInterface e arrancar as informações dela. Dessa forma, posso dizer que tipo de interface é (Ethernet, sem fio, loopback, túnel etc.), se está ativa ou não, e SOOO muito mais.

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

Agora, para obter o endereço IPv4 da sua chamada à interface de rede Ethernet:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Ou sua interface sem fio:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Se você tentar obter um endereço IPv4 para uma interface sem fio, mas o computador não tiver uma placa sem fio instalada, apenas retornará uma string vazia. A mesma coisa com a interface Ethernet.

Espero que isso ajude alguém! :-)

EDITAR:

Observou-se (obrigado @NasBanov) que, embora essa função extraia o endereço IP de uma maneira muito melhor do que usá- Dns.GetHostEntry(Dns.GetHostName())la, ela não funciona muito bem no suporte a várias interfaces do mesmo tipo ou a vários endereços IP em uma única interface . Ele retornará apenas um único endereço IP quando houver vários endereços atribuídos. Para retornar TODOS esses endereços atribuídos, você pode simplesmente manipular a função original para sempre retornar uma matriz em vez de uma única string. Por exemplo:

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

Agora, esta função retornará TODOS os endereços atribuídos para um tipo de interface específico. Agora, para obter apenas uma única string, você pode usar a .FirstOrDefault()extensão para retornar o primeiro item da matriz ou, se estiver vazio, retornar uma string vazia.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
compman2408
fonte
5
Essa é uma solução melhor porque não há usabilidade de DNS em muitos locais e as interfaces podem ter vários endereços IP. Eu também utilizo um método semelhante.
Mert Gülsoy
O problema é que você retorna apenas 1 endereço IP por interface ... o último IP, por exemplo.
Nas Banov 02/03
@ compman2408 - não é verdade, uma única interface pode ter vários IPs, consulte en.wikipedia.org/wiki/Multihoming#Variants para todos os combos. Um exemplo óbvio é ao executar o IPv4 e o IPv6, mas no passado tive um único adaptador Ethernet participando de várias redes IPv4. Incomum talvez - mas perfeitamente legal. Por exemplo, para Windows, consulte windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov
@NasBanov Esta função é configurada apenas para obter endereços IPv4, então nem vou falar sobre IPv6 e sua inutilidade atual. Estou ciente do multihoming como conectar-se a várias redes em várias interfaces, mas nunca ouvi falar de conectar-se a várias redes na mesma interface. Mesmo que você esteja certo de que isso seja realmente possível, <1% das pessoas que usam a NIC dessa maneira precisariam alterar a função para retornar uma matriz.
compman2408
1
Obrigado por isso. Para sua informação, pelo menos no .NET 3.5 mono no OSX item.OperationalStatussempre retorna Unknown.
Gman
36

Aqui está uma versão modificada (do compman2408) que funcionou para mim:

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {  // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards
        string output = "";  // default output
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface
        {  // Find the network interface which has been provided in the arguments, break the loop if found
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {   // Fetch the properties of this adapter
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
                // Check if the gateway adress exist, if not its most likley a virtual network or smth
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {   // Iterate over each available unicast adresses
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {   // If the IP is a local IPv4 adress
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {   // we got a match!
                            output = ip.Address.ToString();
                            break;  // break the loop!!
                        }
                    }
                }
            }
            // Check if we got a result if so break this method
            if (output != "") { break; }
        }
        // Return results
        return output;
    }

Você pode chamar esse método, por exemplo, como:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

A mudança: estou recuperando o IP de um adaptador que possui um IP de gateway atribuído a ele. Segunda alteração: eu adicionei docstrings e break statement para tornar esse método mais eficiente.

Gerardo H
fonte
2
Solução inteligente. Agora estou usando isso.
RQDQ
4
Tem o mesmo problema que o código do qual foi derivado: ele retorna apenas um dos IPs, um IP aleatório de muitos - que não precisa ser o que você precisa. Ele ganha a ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov
1
@NasBanov, claro que ganhei, como afirmo no meu post: "o que funcionou para mim". :-)
Gerardo H
Este é o caminho a seguir, obrigado por isso. Quando você tem comutadores de loopback para emuladores instalados, todas as outras variantes falham enquanto este é bem-sucedido!
DiamondDrake
1
Por que você retorna apenas o último endereço IP encontrado, não o primeiro? Um simpel breakno mais interno ifou um returnfaria o truque.
Martin Mulder
20

Este é o melhor código que encontrei para obter o IP atual, evitando obter o host VMWare ou outro endereço IP inválido.

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()
        : "";
}
rodcesar.santos
fonte
Você provavelmente deve explicar por que esse código é a solução para a resposta. Você pode realmente obter uma resposta sobre a pergunta se estiver conectado à Internet e isso resultar em um erro?
Philipp M
As outras maneiras não usam a validação IsDnsEligible e PrefixOrigin.
Rodcesar.santos 5/12
@PhilippM Se o endereço não for um DNS elegível, é um IP interno reservado. Não é o host do provedor de internet. E se PrefixOrigin foi fornecido por um servidor DHCP, é possível que essa seja a melhor opção de endereço. Esta é a função única que funciona para mim!
Rodcesar.santos
1
@ user1551843 - foi ótimo, obrigado. Eu estava usando o método GetHostByName depreciado antiga, mas foi devolver o IP de um adaptador de VMWare :)
Jason Newland
Esta foi a única solução que funcionou para mim no vpn + wireless. Obrigado.
jay-perigo
12

Eu acho que usar o LinQ é mais fácil:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Kapé
fonte
14
Isso não é LINQ, são métodos de extensão e lambdas. Há uma diferença.
Mark
10
@ Mark - Se você não adicionar "using System.Linq;" você não pode usar o método de extensão "Primeiro" embora
BornToCode 8/15
5
Isso ocorre porque o método de extensão está na classe Enumerable, que está no espaço para nome System.Linq. Ainda não é o LINQ.
Mark
20
Marque, mesmo nesta forma abreviada, a instrução realmente está usando LINQ-to-objects apresentados com sintaxe de método (lambda). A sintaxe da consulta é simplesmente um açúcar sintático que é compilado em uma cadeia de chamadas do método de extensão IEnumerable, que é o que é o LINQ-to-objects. Fontes: criou um provedor LINQ-to-SQL e uma série de artigos sobre o assunto.
constantine g
9

Para rir, pensei em tentar obter uma única instrução LINQ usando o novo operador condicional nulo C # 6. Parece muito louco e provavelmente terrivelmente ineficiente, mas funciona.

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

Cortesia lógica Gerardo H(e por referência compman2408).

Stajs
fonte
Definitivamente divertido (+1), mas na verdade não precisa ser ineficiente. Lembra-me de programação em LISP ou Forth :-)
Roland
6

Outra maneira de obter IP usando a expressão 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();
}
Amirhossein Yari
fonte
5

@ mrcheif Encontrei esta resposta hoje e foi muito útil, embora tenha retornado um IP errado (não devido ao código não funcionar), mas deu o IP de internetwork errado quando você tem coisas como o Himachi em execução.

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;
}
Jordan Trainor
fonte
2
Você quer dizer Logmein Hamachi? É uma solução VPN e mexe com a pilha da rede. Além disso, sendo uma VPN, parece razoável que ele retorne o IP atribuído à VPN quando conectado (apenas meu palpite).
Mrchief
2
Completamente não confiável. Além de 192.0.0.0/8não ser um teste correto para um endereço IP privado (existem três intervalos, todos diferentes deste), pode ser um intervalo de rede corporativa, portanto, não tanto "local".
ivan_pozdeev
5

Testado com uma ou várias placas de rede local e máquinas virtuais

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;
    }
Shanewaj
fonte
Lembre-se de que este está funcionando apenas para Ethernet. Remova a restrição NetworkInterfaceType para oferecer suporte ao wi-fi.
Scor4er 6/08/19
3

Apenas uma versão atualizada minha usando o 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 (var networkInterface in networkInterfaces)
    {
        var adapterProperties = networkInterface.GetIPProperties();

        if (adapterProperties.GatewayAddresses.FirstOrDefault() == null)
                continue;
        foreach (var ip in networkInterface.GetIPProperties().UnicastAddresses)
        {
            if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                    continue;

            return ip.Address;
        }
    }

    return null;
}
Giusepe
fonte
2

Pré-requisitos: você deve adicionar a referência System.Data.Linq e referenciá-la

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));
pola
fonte
2

Eu também estava lutando para obter o IP correto.

Tentei uma variedade de soluções aqui, mas nenhuma me proporcionou o efeito desejado. Quase todos os testes condicionais fornecidos não fizeram com que nenhum endereço fosse usado.

Isto é o que funcionou para mim, espero que ajude ...

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);
UberBiza
fonte
1
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();
Naimish Mungara
fonte
str é sempre esvaziar
aj.toulan
1

Lembre-se de que, no caso geral, você pode ter várias traduções NAT em andamento e vários servidores DNS, cada um operando em diferentes níveis de tradução NAT.

E se você tiver NAT de classe de operadora e quiser se comunicar com outros clientes da mesma operadora? No caso geral, você nunca sabe ao certo porque pode aparecer com nomes de host diferentes a cada tradução NAT.

sgjsfth sthseth
fonte
1

Obsoleto se foi, isso funciona para mim

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}
Sourcephy
fonte
1

Atualizando a resposta de Mrchief com o Linq, teremos:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}
Ashkan Sirous
fonte
1

Isso retorna endereços de qualquer interface que tenha endereços de gateway e endereços unicast em duas listas separadas, IPV4 e IPV6.

public static (List<IPAddress> V4, List<IPAddress> V6) GetLocal()
{
    List<IPAddress> foundV4 = new List<IPAddress>();
    List<IPAddress> foundV6 = new List<IPAddress>();

    NetworkInterface.GetAllNetworkInterfaces().ToList().ForEach(ni =>
    {
        if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null)
        {
            ni.GetIPProperties().UnicastAddresses.ToList().ForEach(ua =>
            {
                if (ua.Address.AddressFamily == AddressFamily.InterNetwork) foundV4.Add(ua.Address);
                if (ua.Address.AddressFamily == AddressFamily.InterNetworkV6) foundV6.Add(ua.Address);
            });
        }
    });

    return (foundV4.Distinct().ToList(), foundV6.Distinct().ToList());
}
Michael Jordan
fonte
Solução pura :)
Johan Franzén
1

Já existem muitas respostas, mas ainda estou contribuindo com a minha:

public static IPAddress LocalIpAddress() {
    Func<IPAddress, bool> localIpPredicate = ip =>
        ip.AddressFamily == AddressFamily.InterNetwork &&
        ip.ToString().StartsWith("192.168"); //check only for 16-bit block
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(localIpPredicate);
}

Um forro:

public static IPAddress LocalIpAddress() => Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().StartsWith("192.168"));

Observação: pesquise da última porque ainda funcionou após algumas interfaces adicionadas ao dispositivo, como MobileHotspot, VPN ou outros adaptadores virtuais sofisticados.

nyconing
fonte
1
Portanto, se meu IP local for 10.0.2.3, ele não será encontrado? Isso é realmente estranho neste código.
frankhommers
@frankhommers foi dito verificar apenas para o bloco de 16 bits
nyconing
16 bits blocos também pode ser algo mais do que 192.168
frankhommers
0

Além disso, apenas um código simples para obter o IP do cliente:

        public static string getclientIP()
        {
            var HostIP = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
            return HostIP;
        }

Espero que ajude você.

Majedur Rahaman
fonte
0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

insira a descrição da imagem aqui

Eran Peled
fonte
5
Sua resposta deve conter uma descrição de como funciona no caso do OP e também para futuros leitores.
Ronak Dhoot 08/03
É melhor incluir uma explicação da sua resposta para futuros leitores.
Nicolas Gervais
0

Código do compman2408 modificado para poder percorrer cada um NetworkInterfaceType.

public static string GetLocalIPv4 (NetworkInterfaceType _type) {
    string output = null;
    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;
}

E você pode chamar assim:

static void Main (string[] args) {
    // Get all possible enum values:
    var nitVals = Enum.GetValues (typeof (NetworkInterfaceType)).Cast<NetworkInterfaceType> ();

    foreach (var nitVal in nitVals) {
        Console.WriteLine ($"{nitVal} => {GetLocalIPv4 (nitVal) ?? "NULL"}");
    }
}
Najeeb
fonte
0
Imports System.Net
Imports System.Net.Sockets
Function LocalIP()
    Dim strHostName = Dns.GetHostName
    Dim Host = Dns.GetHostEntry(strHostName)
    For Each ip In Host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            txtIP.Text = ip.ToString
        End If
    Next

    Return True
End Function

Abaixo da mesma ação

Função IP Local ()

Dim Host como String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString

txtIP.Text = Host

Return True

Função final

YongJae Kim
fonte
Abaixo, o exemplo abaixo é a mesma ação. Função LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host Retornar Função True End
YongJae Kim
-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

uma linha de código: D

Fuzzybear
fonte
7
Pode lançar um OutOfRangeException em alguns casos.
Loudenvier
5
Além disso, como você sabe qual deseja? O que é certo para você pode estar errado para outra pessoa.
Mark
-3

Se você possui máquinas virtuais ou placas de rede extras, pode haver outros valores na lista de endereços. Minha sugestão é verificar as entradas da lista de endereços e imprimir, conforme apropriado. No meu caso, a entrada 3 era o endereço ipv4 da minha máquina

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[3];
string ip = ipAddr.ToString();

Não esqueça de adicionar using System.Net;

Bibaswann Bandyopadhyay
fonte
1
Correção; Todos eles são o endereço IP da sua máquina. Qual você deseja, no entanto, é uma história totalmente diferente. Observe que a ordem pode mudar e, devido ao método que você está usando, sempre adivinhará.
Mark
Isso é o que eu disse, você deve verificar as entradas de addresslist, e sim é adivinhar, mas depois de ver todas as entradas, supondo que não é muito difícil
Bibaswann Bandyopadhyay
Como você saberia o que é apropriado? Usando a solução de compman2048, você saberia pelo menos qual está vinculado a qual interface.
Mark
Essa solução não funcionou no meu computador, porque eu tenho 2 interfaces wlan, 2 máquinas virtuais e 1 emulador, por isso tenho muitos IPs. Mas se você está procurando endereço interno fornecido pelo roteador ele vai começar com 192 ou 172 ou 10, que é como eu entendi
Bibaswann Bandyopadhyay
A menos que seu roteador distribua IPs públicos, o que é incomum, mas possível.
Mark