ASP.NET获取客户端IP及Mac地址

来源:互联网 发布:mac的option键 编辑:程序博客网 时间:2024/04/29 12:13

http://www.itbobo.com/asp-net-to-obtain-client-ip-and-mac-address.html

最近在做电子政务,给某局以及直属单位做统一的用户登录功能。登录界面有多级选择列表,如:局单位-->局业务处室-->局用户-->用户名,每次登录都得这么选择,繁琐的操作对那些机关领导来说确实是一件不容易的事,为此就希望把用户选择的信息,初始化一次,以后登录就不用再选择那么多了。于是就想到记录客户端的MAC地址来做为机器标识。但要在客户端能快速准确的获取到MAC地址还是一件不太容易的事。主要常见的方式有以下几种:

方法一:Javascript结合系统的ActiveX

优点:无需开发额外的代码,轻量级的实现。不需要服务器端进行处理,有客户端自行获取,传递到服务器端,速度比在服务器端获取好。 
缺点:受客服端平台的限制,如安全级别设置较高,则无常正常执行。还有情况就是可靠性不是怎么好,有获取不到的情况。

其实最关键的还是用到两个ActiveX: 
<OBJECT id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></OBJECT> 
<OBJECT id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT>

两个ActiveX都是系统自带,不用去下载或注册。

Code

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2.  
  3. <html>  
  4.     <head><title>WMI Scripting HTML</title>  
  5. <META http-equiv="Content-Type" content="text/html; charset=gb2312">  
  6. <script language="JScript" event="OnCompleted(hResult,pErrorObject, pAsyncContext)" for=foo>  
  7. document.forms[0].txtMACAddr.value=unescape(MACAddr);  
  8. document.forms[0].txtIPAddr.value=unescape(IPAddr);  
  9. document.forms[0].txtDNSName.value=unescape(sDNSName);  
  10.  //document.formbar.submit();  
  11.   </script>  
  12.  
  13. <script language="JScript" event=OnObjectReady(objObject,objAsyncContext) for=foo>  
  14.    if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true)  
  15.    {  
  16.     if(objObject.MACAddress != null && objObject.MACAddress != "undefined")  
  17.     MACAddr = objObject.MACAddress;  
  18.     if(objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) !="undefined")  
  19.     IPAddr = objObject.IPAddress(0);  
  20.     if(objObject.DNSHostName != null && objObject.DNSHostName != "undefined")  
  21.     sDNSName = objObject.DNSHostName;  
  22.     }  
  23.   </script>  
  24.  
  25.     <META content="MSHTML 6.00.2800.1106" name=GENERATOR>  
  26. </head>  
  27. <body>  
  28. <object id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></object>  
  29. <object id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></object>  
  30.    <script language="JScript">  
  31.        var service = locator.ConnectServer();  
  32.        var MACAddr ;  
  33.        var IPAddr ;  
  34.        var DomainAddr;  
  35.        var sDNSName;  
  36.        service.Security_.ImpersonationLevel=3;  
  37.        service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');  
  38.    </script>  
  39.  
  40. <form  runat="server" id="formfoo" name="formbar" method="post">  
  41.     <input  name="txtMACAddr"/>  
  42.     <input  name="txtIPAddr"/>  
  43.     <input  name="txtDNSName"/>  
  44.     <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />  
  45. </form>  
  46. </body>  
  47. </html> 

 

方法二:调用Win32API(推荐)

优点:成功率较高,不受客户浏览器的限制。 
缺点:只能是Windows系统

Code

  1.     [DllImport("Iphlpapi.dll")]  
  2.     private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);  
  3.     [DllImport("Ws2_32.dll")]  
  4.     private static extern Int32 inet_addr(string ip);  
  5.  
  6. private string GetClientIP()  
  7.     {  
  8.         string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];  
  9.         if (null == result || result == String.Empty)  
  10.         {  
  11.             result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];  
  12.         }  
  13.  
  14.         if (null == result || result == String.Empty)  
  15.         {  
  16.             result = HttpContext.Current.Request.UserHostAddress;  
  17.         }  
  18.         return result;  
  19.     }  
  20.  
  21. /// <summary>  
  22.     /// 获取Mac地址信息  
  23.     /// </summary>  
  24.     /// <param name="IP"></param>  
  25.     /// <returns></returns>  
  26.     public static string GetCustomerMac(string IP)  
  27.     {  
  28.         Int32 ldest = inet_addr(IP);  
  29.         Int64 macinfo = new Int64();  
  30.         Int32 len = 6;  
  31.         int res = SendARP(ldest, 0, ref macinfo, ref len);  
  32.         string mac_src = macinfo.ToString("X");  
  33.  
  34.         while (mac_src.Length < 12)  
  35.         {  
  36.             mac_src = mac_src.Insert(0, "0");  
  37.         }  
  38.  
  39.         string mac_dest = "";  
  40.  
  41.         for (int i = 0; i < 11; i++)  
  42.         {  
  43.             if (0 == (i % 2))  
  44.             {  
  45.                 if (i == 10)  
  46.                 {  
  47.                     mac_dest = mac_dest.Insert(0, mac_src.Substring(i, 2));  
  48.                 }  
  49.                 else 
  50.                 {  
  51.                     mac_dest = "-" + mac_dest.Insert(0, mac_src.Substring(i, 2));  
  52.                 }  
  53.             }  
  54.         }  
  55.  
  56.         return mac_dest;  
  57.     } 

 

方法三:后台进程调用nbtstat命令

优点:无需额外开发组件,不受客户端平台的限制 
缺点:受网络范围的限制,成功率较低,速度慢。

具体实现原理:通过nbtstat -a IP 命令将对方计算机的信息输出管道,然后捕获管道输出的内容,再通过正则表达式将MAC筛选出来。

Code

  1. public static string GetCustomerMac(string IP)  
  2. {  
  3.     string dirResults = "";  
  4.     ProcessStartInfo psi = new ProcessStartInfo();  
  5.     Process proc = new Process();  
  6.     psi.FileName = "nbtstat";  
  7.     psi.RedirectStandardInput = false;  
  8.     psi.RedirectStandardOutput = true;  
  9.     psi.Arguments = "-A " + IP;  
  10.     psi.UseShellExecute = false;  
  11.     proc = Process.Start(psi);  
  12.     dirResults = proc.StandardOutput.ReadToEnd();  
  13.     proc.WaitForExit();  
  14.     dirResults = dirResults.Replace("\r""").Replace("\n""").Replace("\t""");  
  15.     Regex reg = new Regex("([0-9A-Fa-f]{2})(-[0-9A-Fa-f]{2}){5}", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.RightToLeft);  
  16.     Match mc = reg.Match(dirResults);  
  17.     if (mc.Success)  
  18.     {  
  19.         try 
  20.         {  
  21.             return mc.Groups[0].Value.ToString();  
  22.         }  
  23.         catch 
  24.         {  
  25.             return "";  
  26.         }  
  27.     }  
  28.     else 
  29.     {  
  30.         reg = new Regex("Host not found", RegexOptions.IgnoreCase | RegexOptions.Compiled);  
  31.         mc = reg.Match(dirResults);  
  32.         if (mc.Success)  
  33.         {  
  34.             return "Host not found!";  
  35.         }  
  36.         else 
  37.         {  
  38.             return "";  
  39.         }  
  40.     }  

 

上述三种方式,都经过测试,第一种方式,会有获取不到MAC地址的情况;第三种方式,奇慢无比,尤其当服务器有多个网卡时,相当慢。我自己的机器有两个网卡时,程序基本卡死,半天才能响应;改成第二种之后,情况改观了很多,效率都还不错。如果使用ASP.NET获取MAC地址,推荐使用第二种方式。

0 0