DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ホスト名からIPアドレス、IPアドレスからホスト名を取得する

ここでは、ホスト名からIPアドレスを取得する方法(例えば「www.yahoo.com」から「66.218.71.81」)、およびIPアドレスからホスト名を取得する方法(例えば「66.218.71.81」から「w1.scd.yahoo.com」)を紹介します。

Dns.GetHostEntryメソッドを使用する方法

Dns.GetHostEntryメソッド(.NET Framework 1.1以前では、Dns.ResolveメソッドまたはDns.GetHostByNameメソッドDns.GetHostByAddressメソッド)を使用すると、ホスト名やIPアドレスを示す文字列から、IPHostEntryオブジェクトを取得できます。そして、IPHostEntry.AddressListプロパティでIPアドレスを、IPHostEntry.HostNameプロパティでホスト名を取得できます。

まず、この方法でホスト名からIPアドレスを取得する例を示します。

なお、ここで紹介しているサンプルは例外処理を省略していますが、GetHostEntryメソッド(および、Resolve、GetHostByName、GetHostByAddress、BeginGetHostEntry、GetHostAddressesメソッド)はホスト名が見つからなかった時などに例外SocketExceptionをスローしますので、通常はキャッチするようにしてください。

VB.NET
コードを隠すコードを選択
'解決したいホスト名
Dim hostName As String = "www.yahoo.com"

'IPHostEntryオブジェクトを取得
Dim iphe As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(hostName)

'.NET Framework 1.1以前では次のようにする
'Dim iphe As System.Net.IPHostEntry = System.Net.Dns.Resolve(hostName)
'または
'Dim iphe As System.Net.IPHostEntry = System.Net.Dns.GetHostByName(hostName)

'IPアドレスのリストを取得
Dim adList As System.Net.IPAddress() = iphe.AddressList

'IPアドレスを列挙
Dim i As Integer
For i = 0 To adList.Length - 1
    Console.WriteLine(adList(i).ToString())
Next
C#
コードを隠すコードを選択
//解決したいホスト名
string hostName = "www.yahoo.com";

//IPHostEntryオブジェクトを取得
System.Net.IPHostEntry iphe = System.Net.Dns.GetHostEntry(hostName);

//.NET Framework 1.1以前では次のようにする
//System.Net.IPHostEntry iphe = System.Net.Dns.Resolve(hostName);
//または
//System.Net.IPHostEntry iphe = System.Net.Dns.GetHostByName(hostName);

//IPアドレスのリストを取得
System.Net.IPAddress[] adList = iphe.AddressList;

//IPアドレスを列挙
for (int i = 0; i < adList.Length; i++)
{
    Console.WriteLine(adList[i].ToString());
}

次に、IPアドレスからホスト名を取得する例を示します。

VB.NET
コードを隠すコードを選択
'解決したいIPアドレス
Dim ipAdd As String = "106.10.139.246"

'IPHostEntryオブジェクトを取得
Dim iphe As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(ipAdd)

'.NET Framework 1.1以前では次のようにする
'Dim iphe As System.Net.IPHostEntry = System.Net.Dns.Resolve(ipAdd)
'または
'Dim iphe As System.Net.IPHostEntry = System.Net.Dns.GetHostByAddress(ipAdd)

'ホスト名を取得
Console.WriteLine(iphe.HostName)
C#
コードを隠すコードを選択
//解決したいIPアドレス
string ipAdd = "106.10.139.246";

//IPHostEntryオブジェクトを取得
System.Net.IPHostEntry iphe = System.Net.Dns.GetHostEntry(ipAdd);

//.NET Framework 1.1以前では次のようにする
//System.Net.IPHostEntry iphe = System.Net.Dns.Resolve(ipAdd);
//または
//System.Net.IPHostEntry iphe = System.Net.Dns.GetHostByAddress(ipAdd);

//ホスト名を取得
Console.WriteLine(iphe.HostName);
補足:ここで紹介している方法では、DNSサーバーとして既定のサーバーを使用し、別のサーバーを使用することはできません。任意のDNSサーバーを使用したいという場合は、「DNSサーバーと直接やり取りして、A、PTR、MX等のレコードを検索する」をご覧ください。
補足:Dns.GetHostEntryメソッドに空の文字列を渡すと、ローカルホストのIPv4アドレスが返されます。
補足:取得したIPアドレスがIPv4かIPv6かは、IPAddressオブジェクトのAddressFamilyプロパティがInterNetworkかInterNetworkV6かで判断できます。
補足:ローカルコンピューターにIPv6がインストールされていない場合は、Dns.GetHostEntryメソッドの結果からIPv6アドレスが除外されます。

GetHostByAddressが成功してもGetHostEntryでは失敗するかもしれない理由

GetHostByAddress(または、Resolve)メソッドでは成功するのに、GetHostEntryメソッドでは失敗する場合があります。これについては、MSDNのDns.GetHostEntryメソッドに説明があります。以下にその一部を引用します。

GetHostEntry メソッドは、hostNameOrAddress パラメーターで IP リテラル文字列が渡されると、すべてのプロパティ セットと共に返される IPHostEntry インスタンスがそのアプリケーションから要求されると見なします。 これらのプロパティには、AddressList、Aliases、HostName などがあります。 その結果、GetHostEntry メソッドの実装は、IP リテラル文字列が渡されると次の動作を示します。

  1. メソッドは、アドレスの解析を試みます。 hostNameOrAddress パラメーターが有効な IP リテラル文字列を含む場合、最初のフェーズは成功します。
  2. ホスト名を取得するため、IP リテラル文字列の IP アドレスを使用した逆引き参照が試行されます。 この結果は HostName プロパティとして設定されます。
  3. この逆引き参照から得たホスト名をもう一度使用して、名前に関連するすべての IP アドレス候補が取得され、AddressList プロパティとして設定されます。

IPv4 のリテラル文字列の場合、前の 3 つの手順はすべて成功します。 ただし、IPv4 の古い DNS レコードの場合は、実際には別のホストに所属するアドレスが返される可能性もあります。 これにより手順 3. が失敗し、例外が返される場合があります (IPv4 アドレスの DNS PTR レコードはあるが、IPv4 アドレスの DNS A レコードはない)。

IPv6 の場合、前の手順 2. は失敗する可能性があります。これは、ほとんどの IPv6 展開が IPv6 アドレスのリバース (PTR) レコードを登録していないためです。 したがって、このメソッドは IPv6 リテラル文字列を完全修飾ドメイン (FQDN) ホスト名として HostName プロパティに返す可能性があります。

つまり、GetHostEntryメソッドは、パラメーターで渡されたIPアドレスを逆引きしてホスト名を取得した後、そのホスト名を使用して正引きが行われます。逆引きだけでなく、正引きが失敗しても、例外(SocketException)が発生します。

一方GetHostByAddressメソッドは、逆引きだけを行い、正引きは行いません。よって、逆引きさえできれば、成功します。

もしかしたら、正引きができないホスト名でもいいから取得したいという場合もあるかもしれません。しかし2.0以降の.NET Frameworkでは、その方法が用意されていません。どうしてもという場合は、「DNSサーバーと直接やり取りして、A、PTR、MX等のレコードを検索する」で紹介しているような方法になります。

非同期で取得する

Dns.GetHostEntryメソッドの代わりにDns.BeginGetHostEntryメソッドDns.EndGetHostEntryメソッドを使うと、非同期でホスト名やIPアドレスを解決することができます。

.NET Framework 1.1以前の場合は、Resolveメソッドの代わりにBeginResolveとEndResolveメソッド、GetHostByNameメソッドの代わりにBeginGetHostByNameとEndGetHostByNameメソッドを使います。

以下に、Dns.BeginGetHostEntryとEndGetHostEntryメソッドを使用して、ホスト名からIPアドレスを取得する例を示します。

VB.NET
コードを隠すコードを選択
'Button1のClickイベントハンドラ
Private Sub Button1_Click(sender As Object, e As EventArgs) _
    Handles Button1.Click

    '解決したいホスト名
    Dim hostName As String = "www.yahoo.com"

    'ホスト名を非同期的に解決する
    System.Net.Dns.BeginGetHostEntry(hostName, _
        New AsyncCallback(AddressOf GetHostEntryCallback), Nothing)
End Sub

'非同期要求が終了した時に呼び出されるコールバックメソッド
Public Shared Sub GetHostEntryCallback(ar As IAsyncResult)
    '非同期要求を終了させて、IPHostEntryオブジェクトを取得
    Dim iphe As System.Net.IPHostEntry = System.Net.Dns.EndGetHostEntry(ar)

    'IPアドレスのリストを取得
    Dim adList As System.Net.IPAddress() = iphe.AddressList

    'IPアドレスを列挙
    Dim i As Integer
    For i = 0 To adList.Length - 1
        Console.WriteLine(adList(i).ToString())
    Next
End Sub
C#
コードを隠すコードを選択
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //解決したいホスト名
    string hostName = "www.yahoo.com";

    //ホスト名を非同期的に解決する
    System.Net.Dns.BeginGetHostEntry(hostName,
        new AsyncCallback(GetHostEntryCallback), null);
}

//非同期要求が終了した時に呼び出されるコールバックメソッド
public static void GetHostEntryCallback(IAsyncResult ar)
{
    //非同期要求を終了させて、IPHostEntryオブジェクトを取得
    System.Net.IPHostEntry iphe = System.Net.Dns.EndGetHostEntry(ar);

    //IPアドレスのリストを取得
    System.Net.IPAddress[] adList = iphe.AddressList;

    //IPアドレスを列挙
    for (int i = 0; i < adList.Length; i++)
    {
        Console.WriteLine(adList[i].ToString());
    }
}

Dns.GetHostAddressesメソッドを使用する方法

ホスト名からIPアドレスを取得する時は、Dns.GetHostAddressesメソッドを使用することもできます。このメソッドは、.NET Framework 2.0以降で使用できます。

Dns.GetHostAddressesメソッドを使用して、ホスト名からIPアドレスを取得する例を示します。

VB.NET
コードを隠すコードを選択
'解決したいホスト名
Dim hostName As String = "www.yahoo.com"

'IPアドレスのリストを取得
Dim adList As System.Net.IPAddress() = _
    System.Net.Dns.GetHostAddresses(hostName)

'IPアドレスを列挙
Dim i As Integer
For i = 0 To adList.Length - 1
    Console.WriteLine(adList(i).ToString())
Next
C#
コードを隠すコードを選択
//解決したいホスト名
string hostName = "www.yahoo.com";

//IPアドレスのリストを取得
System.Net.IPAddress[] adList = System.Net.Dns.GetHostAddresses(hostName);

//IPアドレスを列挙
for (int i = 0; i < adList.Length; i++)
{
    Console.WriteLine(adList[i].ToString());
}

Dns.GetHostAddressesメソッドはDns.GetHostEntryメソッドとほぼ同じですが、違いもあります。引数にIPリテラル文字列(IPアドレスとして解析できる文字列)を指定すると、GetHostAddressesメソッドは解析されたIPアドレスを直ちに返します。GetHostEntryメソッドの場合は、前述したMSDNからの引用にあるように、解析後、そのIPアドレスを使用した逆引き参照が試行されます。

Dns.GetHostAddressesメソッドと同じことを非同期で行うには、Dns.BeginGetHostAddressesメソッドDns.EndGetHostAddressesメソッドを使用します。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。