web-dev-qa-db-ja.com

ローカル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#でネットワークに接続されているかどうか、そしてLANのIPアドレスを取得するのかどうかを確認する方法はありますか。

241
Tono Nam

ローカル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();

395
Mrchief

ローカルマシンで利用可能なマルチIPアドレスがある場合、より正確な方法があります。 UDPソケットをConnectに指定し、そのローカルエンドポイントを読み取ります。

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

UDPソケット上のConnectは次のような効果を持ちます:それはSendRecvの宛先を設定し、他のアドレスからのすべてのパケットを捨て、そして - これは私たちが使うものです - ソケットを "connected"状態に転送し、適切なフィールドを設定します。これには、システムのルーティングテーブルに従って宛先への経路の存在を確認し、それに応じてローカルエンドポイントを設定することが含まれます。最後の部分は公式には文書化されていないようですが、バージョンやディストリビューションを越えてWindows _ /とLinux の両方で確実に動作する BerkeleyソケットAPI (UDP "connected"状態の副作用)の不可欠な特徴。

そのため、このメソッドは指定されたリモートホストへの接続に使用されるローカルアドレスを提供します。実際の接続が確立されていないため、指定されたリモートIPに到達できない可能性があります。

175

Linqを活用するためのMrcheifのコードのリファクタリング(つまり、.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);
}

:)

102
Pure.Krome

私はこれが死んだ馬を蹴っているのかもしれませんが、多分これは誰かを助けることができます。私は自分のローカルIPアドレスを見つける方法をいたるところで探しましたが、それが見つかるところはどこでも使うことを言っています:

Dns.GetHostEntry(Dns.GetHostName());

コンピュータに割り当てられたすべてのアドレスを取得するだけなので、これはまったく好きではありません。複数のネットワークインターフェースがある場合(これはほとんどすべてのコンピューターが現在行っていることです)、どのアドレスがどのネットワークインターフェースに対応するのかわかりません。たくさんの調査を行った後、NetworkInterfaceクラスを使用してそこから情報を取り出すための関数を作成しました。このようにして、私はそれがどんなタイプのインターフェース(イーサネット、ワイヤレス、ループバック、トンネルなど)であるか、それがアクティブであるかどうか、そしてはるかにもっと多くを知ることができます。

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アドレスを得るために:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

またはあなたの無線インターフェース:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

無線インタフェース用のIPv4アドレスを取得しようとしても、コンピュータに無線カードがインストールされていない場合は、空の文字列が返されるだけです。イーサネットインターフェースでも同じことが言えます。

これが誰かに役立つことを願っています! :-)

編集:

この関数はDns.GetHostEntry(Dns.GetHostName())を使用するよりもはるかに良い方法でIPアドレスを抽出することを目的としていますが、同じタイプの複数のインタフェースや単一の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();
}

現在、この関数は特定のインターフェースタイプに割り当てられたすべてのアドレスを返します。 1つの文字列だけを取得するには、.FirstOrDefault()拡張子を使用して配列の最初の項目を返すか、空の場合は空の文字列を返します。

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
89
compman2408

これは私のために働いた(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を取得しています。

22
Gerardo H

これは私が現在のIPを取得するために見つけた最高のコードで、VMWareホストや他の無効な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()
        : "";
}
18
rodcesar.santos

LinQを使うほうが簡単だと思います。

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
8
Kapé

笑うために、私は新しいC#6 null条件付き演算子を使って単一のLINQステートメントを試してみることを考えていました。かなりクレイジーに見えて、恐ろしく非効率的に見えますが、うまくいきます。

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を参照)に基づいて提供されています。

4
Stajs

@ mrcheif今日私はこの答えを見つけました、そしてそれは間違ったIPを返したけれどもそれは非常に役に立ちました(コードが機能していなかったせいではありません)。

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;
}
4
Jordan Trainor

1つまたは複数の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;
    }
4
Shanewaj

Linq式を使ってIPを取得する他の方法:

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

前提条件:System.Data.Linq参照を追加してそれを参照する必要があります。

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

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

私はまた正しい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);
1
UberBiza

LinqでMrchiefの答えを更新すると、次のようになります。

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

一般的なケースでは、複数のNATの翻訳と、それぞれが異なる[NATの翻訳レベルで動作する複数のdnsサーバーがある可能性があります。

キャリアグレードのNATを使用していて、同じキャリアの他の顧客と通信したい場合はどうしますか?一般的な場合、NAT変換ごとに異なるホスト名で表示される可能性があるため、確実にはわかりません。

1
sgjsfth sthseth

時代遅れになってしまった、これは私に働く

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}
1
Sourcephy
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();
1
Naimish Mungara

さらに、クライアントIPを取得するための単純なコード:

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

それがあなたを助けることを願っています。

0
Majedur Rahaman