前几天有人问我如何在ASP.NET中获取客户端的MAC地址,当时没多想,google了一段代码给他,如下所示:

Code
[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);
private void GetMacByARP()
{
try
{
string userip = Request.UserHostAddress;
string strClientIP = Request.UserHostAddress.ToString().Trim();
Int32 ldest = inet_addr(strClientIP); //目的地的ip
Int32 lhost = inet_addr(""); //本地服务器的ip
Int64 macinfo = new Int64();
Int32 len = 6;
int res = SendARP(ldest, 0, ref macinfo, ref len);
string mac_src = macinfo.ToString("X");
if (mac_src == "0")
{
if (userip == "127.0.0.1")
Response.Write("正在访问Localhost!");
else
Response.Write("欢迎来自IP为" + userip + "的朋友!" + "<br>");
return;
}
while (mac_src.Length < 12)
{
mac_src = mac_src.Insert(0, "0");
}
string mac_dest = "";
for (int i = 0; i < 11; i++)
{
if (0 == (i % 2))
{
if (i == 10)
{
mac_dest = mac_dest.Insert(0, mac_src.Substring(i, 2));
}
else
{
mac_dest = "-" + mac_dest.Insert(0, mac_src.Substring(i, 2));
}
}
}
Response.Write("欢迎来自IP为" + userip + "<br>" + ",MAC地址为" + mac_dest + "的朋友!"
+ "<br>");
}
catch (Exception err)
{
Response.Write(err.Message);
}
}
后来跟我说,他本地测试还是可以用的,上传到外网服务器上就不行了,瞄一下,的确,利用ARP数据包来获取MAC地址,在不同网段应该是不行滴。想想,最保险的办法还应是在客户端取得MAC,然后主动发送给服务器,这就要仰仗下javascript了(本人讨厌vbscript),再google了下,在这里找到了解决办法:
http://zhupan.javaeye.com/blog/26440
不过看到所提供的代码有点乱,而且不方便调用,于是乎改造了一下,如下所示:

Code
document.write("<OBJECT id='locator' classid='CLSID:76A64158-CB41-11D1-8B02-00600806D9B6' VIEWASTEXT></OBJECT>");
document.write("<OBJECT id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT>");
var MACAddr, IPAddr, sDNSName
function getObject(objObject,objAsyncContext){
if(objObject.MACAddress != null && objObject.MACAddress != "undefined")
MACAddr = objObject.MACAddress;
if(objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined")
IPAddr = objObject.IPAddress(0);
if(objObject.DNSHostName != null && objObject.DNSHostName != "undefined")
sDNSName = objObject.DNSHostName;
}
function setValue(hResult,pErrorObject, pAsyncContext){
createTxt("txtMAC", MACAddr);
createTxt("txtIp", IPAddr);
createTxt("txtPCName", sDNSName);
}
function createTxt(txtName, txtValue){
var macTxt = document.createElement("INPUT");
macTxt.name = txtName;
macTxt.value = txtValue;
macTxt.type = "hidden";
document.forms[0].appendChild(macTxt);
}
document.getElementById("foo").attachEvent("OnObjectReady", getObject);
document.getElementById("foo").attachEvent("OnCompleted", setValue);
var service = locator.ConnectServer();
var MACAddr ;
var IPAddr ;
var DomainAddr;
var sDNSName;
service.Security_.ImpersonationLevel=3;
service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');
把这段JS保存到js文件里,然后在web页里直接引用就可以了,无需主动调用某个函数。服务端取MAC地址时:Request.Form["txtMAC"],顺带提供了txtIp和txtPCName两个值。注意,可能需要设置下IE权限。
顺带提一下,对于用object调用的组件对象的事件,除了在script标签里用event和for属性来指定事件处理器外,还可以用attachEvent来完成,若需要事件里传递的参数,只要保证入参顺序与出参一致就OK了(可参考《javascript高级程序设计》里讲arguments的那一段)。
:-)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步