如何在C#中获得IP?

  利用dns类和WMI规范获取IP及MAC地址

在C#编程中,要获取主机名和主机IP地址,是比较容易的.它提供的Dns类,可以轻松的取得主机名和IP地址.

示例
:
string strHostName = Dns.GetHostName(); //得到本机的主机名

IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP
string strAddr = ipEntry.AddressList[0].ToString(); //假设本地主机为单网卡


在这段代码中使用了两个类,一个是Dns类,另一个为IPHostEntry类,二者都存在于命名空间System.Net中.
Dns类主要是从域名系统(DNS)中检索关于特定主机的信息,上面的代码第一行就从本地的DNS中检索出本地主机名
.
IPHostEntry类则将一个域名系统或主机名与一组IP地址相关联,它与DNS类一起使用,用于获取主机的IP地址组
.
要获取远程主机的IP地址,其方法也是大同小异
.

在获取了IP地址后,如果还需要取得网卡的MAC地址,就需要进一步探究了
.
这里又分两种情况,一是本机MAC地址,二是远程主机MAC地址.二者的获取是完全不同的
.
在获取本机的MAC地址时,可以使用WMI规范,通过SELECT语句提取MAC地址.在.NET框架中,WMI规范的实现定义在System.Management命名空间中
.
ManagementObjectSearcher类用于根据指定的查询检索管理对象的集合

ManagementObjectCollection类为管理对象的集合,下例中由检索对象返回管理对象集合赋值给它.

示例
:
ManagementObjectSearcher query =new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration") ;
ManagementObjectCollection queryCollection = query.Get();
foreach( ManagementObject mo in queryCollection )
{
   if(mo["IPEnabled"].ToString() == "True")
   mac = mo["MacAddress"].ToString();
}

获取远程主机的MAC地址时,需要借用API函数SendARP.该函数使用ARP协议,向目的主机发送ARP包,利用返回并存储在高速缓存中的IP和MAC地址对,从而获取远程主机的MAC地址
.

示例
:
Int32 ldest= inet_addr(remoteIP); //目的
ip
Int32 lhost= inet_addr(localIP); //本地
ip

try
{
   Int64 macinfo = new Int64();
   Int32 len = 6;
   int res = SendARP(ldest,0, ref macinfo, ref len); //发送ARP包

   return Convert.ToString(macinfo,16);
}
catch(Exception err)
{
   Console.WriteLine("Error:{0}",err.Message);
}
return 0.ToString();

但使用该方式获取MAC时有一个很大的限制,就是只能获取同网段的远程主机MAC地址.因为在标准网络协议下,ARP包是不能跨网段传输的,故想通过ARP协议是无法查询跨网段设备MAC地址的。

示例程序:

using System.Net;
using System;
using System.Management;
using System.Runtime.InteropServices;

public class getIP
{
   [DllImport("Iphlpapi.dll")]
   private static extern int SendARP(Int32 dest,Int32 host,ref Int64 mac,ref Int32 length);
   [DllImport("Ws2_32.dll")]
   private static extern Int32 inet_addr(string ip);

   //获取本机的
IP
   public string getLocalIP()
   {
    string strHostName = Dns.GetHostName(); //得到本机的主机名

    IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP
    string strAddr = ipEntry.AddressList[0].ToString();
    return(strAddr);
   }
   //获取本机的
MAC
   public string getLocalMac()
   {
    string mac = null;
    ManagementObjectSearcher query =new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration") ;
    ManagementObjectCollection queryCollection = query.Get();
    foreach( ManagementObject mo in queryCollection )
    {
      if(mo["IPEnabled"].ToString() == "True")
        mac = mo["MacAddress"].ToString();
    }
    return(mac);
   }

   //获取远程主机
IP
   public string[] getRemoteIP(string RemoteHostName)
   {
    IPHostEntry ipEntry = Dns.GetHostByName(RemoteHostName);
    IPAddress[] IpAddr = ipEntry.AddressList;
    string[] strAddr = new string[IpAddr.Length];
    for (int i=0;i<IPADDR.LENGTH;I++)
    {
     strAddr[i] = IpAddr[i].ToString();
    }
    return(strAddr);
   }
   //获取远程主机
MAC
   public string getRemoteMac(string localIP, string remoteIP)
   {
    Int32 ldest= inet_addr(remoteIP); //目的
ip
    Int32 lhost= inet_addr(localIP); //本地
ip
  
    try
    {
     Int64 macinfo = new Int64();
     Int32 len = 6;
     int res = SendARP(ldest,0, ref macinfo, ref len);
     return Convert.ToString(macinfo,16);
    }
    catch(Exception err)
    {
     Console.WriteLine("Error:{0}",err.Message);
    }
    return 0.ToString();
   }
  
  
   public static void Main(string[] args)
   {
    getIP gi = new getIP();
    Console.WriteLine("本地网卡信息
:");
    Console.WriteLine(gi.getLocalIP() + " - " + gi.getLocalMac());
   
    Console.WriteLine("/n/r远程网卡信息
:");
    string[] temp = gi.getRemoteIP("scmobile-tj2");
    for(int i=0;i<TEMP.LENGTH;I++)
    {
         Console.WriteLine(temp[i]);
    }
    Console.WriteLine(gi.getRemoteMac("192.168.0.3","192.168.0.1"));
   }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ArpSender是C#写的ARP发包器,写的初衷是想试下什么样的ARP包才会引起ARP攻击,构造一些包可能会导致别人上不了网。至于包怎么填,发挥大家的想象吧,嘿嘿。 ArpSender用了SharpPcap这个开源API,有兴趣的到网上查下,用起来挺简单的。编程过程最大的问题就是线程的问题。发包的代码用了BackgroundWorker控件,因为参数只能传一个,并且线程是不允许直接调用主窗口控件,后来用了一个结构体struct ArpPac来传,感觉还是很麻烦啊!不过还好在BackgroundWorker的RunWorkerCompleted可以直接操作主窗口控件了,能把结果显示到主窗口上。 在编写获取IP的MAC地址部分,一开始还是用BackgroundWorker,在获取存在的IP地址MAC时可以正常工作,可是当IP不存在是,DOWORK方法一直没结束。因为里面一个Resolve方法一直没返回,也没超时设定,线程就一直卡在那不动了。也不知道该怎么结束这个线程。于是改用了Thread,传参数用了个object数组,嘿嘿,所有参数都封起来。到了那边再解封,很好用。后来才发现,线程是没有返回值的。。又不能直接操作窗体控件。。没办法,只好设个全局变量来保存结果了。获取MAC部分还用了个Timer控件,1秒钟如果还没得到返回的MAC,直接结束该线程。。。 BackgroundWorker 用起来简单也很好用,如果有个abort方法的话。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值