Windows上获得IP地址的四种方法

最近在看网络编程(主要是TCP/IP通信的)的内容,还研究了下WMI。把获得IP地址的方法总结如下。
1.      使用ipconfig程序。
在命令行下使用命令ipconfig可以得到本机的每个有效网罗接口的IP网絡信息。如果在代码中,可以使用Process.Start()方法来调用ipconfig,然后使用正则表达式来解析结果──当然这样做太繁了,不实用。但我曾经使用类似的方法在代码中获得MAC地址
2.      查找注册表。
使用注册表的麻烦之处在于各个版本的Windows在不同的地方存放网絡信息。
Windows98&Windows Me
注册表中的位置为:
          HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Class\NetTrans
在这下面,每个Key对应一个网络设备的信息(IPAddress,DefaultGateway,IPMask)。
   Windows NTWindows 2000&Windows XP
  和Windows98,Me不同,先要得知有哪些网卡,然后再查此网卡的网絡信息。第一步:找到网卡,地址为:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\NetworkCards,从中得到ServiceName值;
第二步:根据上面得到的ServiceName值到下面地址查找:
HKEY_LOCAL_MACHINE\CurrentControlSet\Services,找到响应的Key后,在parameters\tcpip下可以得到网络设备的信息(IPAddress,DefaultGateway,IPMask)。另外,对于动态的IP地址,可能得去查找DHCPIPAddress注册表對應关键词的值。
3.      使用WMI。
查询表Win32_NetworkAdapterConfiguration即可获得。
4.      使用DNS。
 
代码如下:
using System;
using Microsoft.Win32;
using System.Management;
using System.Net;
namespace IPAddress
{
    
class MainClass
    
{
        
/// <summary>
        
/// 應用程式的主進入點。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            GetIPByRegistry();
            GetIPByWMI();
            GetIPByDns();
            Console.ReadLine();
        }


        
#region Methods
        
private const string CARDKEY = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards";
        
private const string SERVICEKEY = @"SYSTEM\CurrentControlSet\Services\";
        
public static void GetIPByRegistry()
        
{
            RegistryKey entry 
= Registry.LocalMachine;
            RegistryKey services 
= entry.OpenSubKey(CARDKEY);
            
if ( services == null)
                
return;

            
string[] cards = services.GetSubKeyNames();
            services.Close();

            
foreach (string key in cards )
            
{
                RegistryKey cardService 
= entry.OpenSubKey(CARDKEY + "\\" +key);
                
if ( cardService == null )
                    
return;
                
string serviceName = cardService.GetValue("ServiceName").ToString();
                Console.WriteLine(
"\n Network card : {0}",serviceName);
                
                RegistryKey networkCard 
= entry.OpenSubKey(SERVICEKEY+serviceName+"\\Parameters\\Tcpip");
                
if ( networkCard != null )
                
{
                    
string[] ips = (string[]) networkCard.GetValue("IPAddress");
                    
foreach ( string ip in ips)
                    
{
                        Console.WriteLine(
" The IPAddress is  :{0}",ip);
                    }

                    networkCard.Close();
                }

                entry.Close();
            }

        }


        
public static void GetIPByWMI()
        
{
            
string query = "select IPAddress from Win32_NetworkAdapterConfiguration where IPEnabled='TRUE'";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher(query);
            ManagementObjectCollection collection 
= searcher.Get();
            
foreach ( ManagementObject mo in collection )
            
{
                
string[] ips = (string[])mo["IPAddress"];
                
foreach ( string ip in ips )
                
{
                    Console.WriteLine(
" Network card ip is :{0}",ip);
                }

            }

        }


        
public static void GetIPByDns()
        
{
            System.Net.IPAddress[] ips 
= Dns.GetHostByName(Dns.GetHostName()).AddressList;
            
foreach ( System.Net.IPAddress ip in ips )
            
{
                Console.WriteLine(
"The ip is : {0}",ip.ToString());
            }

        }

        
#endregion

    }

}

posted @ 2005-06-15 11:27 风满袖 阅读(6238) 评论(8) 编辑 收藏

 回复 引用   
#1楼 2005-06-15 15:21 网际浪子
提几个问题:
1、用注册表时如果一台机器有多个网卡,或安装后将网卡换过插槽,那键值找的就不对了。

2、用WMI,没有插网线的时候好像也不行。

 回复 引用 查看   
#2楼[楼主] 2005-06-15 15:29 James      
@网际浪子:
其實都不是完全之策.使用dns的話,如果dns服務沒有啟動,則也不能得到ip地址.

1.註冊表是存在這個問題.
2.沒有試過,如果連結的是本機的話,應該是沒有問題的.

 回复 引用 查看   
#3楼[楼主] 2005-06-15 15:32 James      
剛實驗了下子,没有插网线的时候,我連結本機WMI是正常的
 回复 引用   
#4楼 2005-06-16 12:42 li-new
也可以用Socket.LocalEndPoint属性
 回复 引用 查看   
#5楼[楼主] 2005-06-16 12:57 James      
@li-new :
你錯了.這個屬性是在你進行了Socket.Bind()才有值的.
怎麼能用這個來取呢!

 回复 引用   
#6楼 2005-06-16 16:11 li-new
你可以测试以下,当你new一个Socket后就可以用它的LocalEndPoint来取得本地的IP地址以及随即大于1024的端口!
 回复 引用 查看   
#7楼[楼主] 2005-06-16 18:02 James      
msdn :
LocalEndPoint 屬性通常會在您呼叫 Bind 方法之後才加以設定。如果您允許系統指派通訊端的本機 IP 位址和連接埠編號,則 LocalEndPoint 屬性將會在第一個 I/O 作業之後被設定。對連接導向通訊協定來說,第一個 I/O 作業將會是對 Connect 或 Accept 方法的呼叫。

 回复 引用   
#8楼 2005-06-17 09:49 adoer
不错,很实用的文章