请问如何在VB.NET中根据ip获取远程机器的MAC地址??

zhangxueq 2003-12-02 06:48:00
请问如何在VB.NET中根据ip获取远程机器的MAC地址??
...全文
483 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
dhcfzc 2003-12-05
  • 打赏
  • 举报
回复
真正的正确解决方案!!!
Imports System.Runtime.InteropServices
Imports System.Net
Imports System.Net.Sockets


Public Class WebForm1
Inherits System.Web.UI.Page

#Region " Web 窗体设计器生成的代码 "

'该调用是 Web 窗体设计器所必需的。
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

End Sub
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents TextBox2 As System.Web.UI.WebControls.TextBox
Protected WithEvents TextBox3 As System.Web.UI.WebControls.TextBox
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
Protected WithEvents Label2 As System.Web.UI.WebControls.Label
Protected WithEvents Label3 As System.Web.UI.WebControls.Label

'注意: 以下占位符声明是 Web 窗体设计器所必需的。
'不要删除或移动它。
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: 此方法调用是 Web 窗体设计器所必需的
'不要使用代码编辑器修改它。
InitializeComponent()
End Sub

#End Region
Private Declare Function inet_addr Lib "wsock32.dll" _
(ByVal s As String) As Int32

Private Declare Function SendARP Lib "iphlpapi.dll" _
(ByVal DestIP As Int32, _
ByVal SrcIP As Int32, _
ByRef pMacAddr As Byte, _
ByRef PhyAddrLen As IntPtr) As Long

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim ip As String = Request.UserHostAddress 'IP地址
Dim ldest As Int32 = inet_addr(ip) '构造IP地址
Dim pulMac(6) As Byte 'MAC地址
Dim ulLen As IntPtr = New IntPtr(10) 'MAC地址的位数
Dim hr As Long
hr = SendARP(ldest, 0, pulMac(0), ulLen) 'hr=0

Dim i As Int32
Dim tmp As String
Dim li As Int32 = ulLen.ToInt32
TextBox3.Text = ip

For i = 0 To li - 1
If pulMac(i) = 0 And i <> li - 1 Then
tmp = tmp & "00-"
ElseIf pulMac(i) = 0 And i = li - 1 Then
tmp = tmp & "00"
Else
If Hex$(pulMac(i)).Length = 1 And i <> li - 1 Then
tmp = tmp + "0"
tmp = tmp & Hex$(pulMac(i)) & "-"
ElseIf Hex$(pulMac(i)).Length <> 1 And i <> li - 1 Then
tmp = tmp & Hex$(pulMac(i)) & "-"
ElseIf Hex$(pulMac(i)).Length = 1 And i <> li - 1 Then
tmp = tmp + "0"
tmp = tmp & Hex$(pulMac(i))
Else
tmp = tmp & Hex$(pulMac(i))
End If

End If

Next
TextBox1.Text = tmp
DisplayHostAddress(ip)
End Sub
Public Sub DisplayHostAddress(ByVal IpAddressString As [String])
Try
Dim hostIPAddress As IPAddress = IPAddress.Parse(IpAddressString)

' Call the GetHostByAddress(IPAddress) method, passing an IPAddress object as an argument
' to obtain an IPHostEntry instance, containing address information for the specified host.

Dim hostInfo As IPHostEntry = Dns.GetHostByAddress(hostIPAddress)
' Get the IP address list that resolves to the host names contained in
' the Alias property.
Dim address As IPAddress() = hostInfo.AddressList
' Get the alias names of the above addresses in the IP address list.
Dim [alias] As [String]() = hostInfo.Aliases

'Response.Write("Host name : " + hostInfo.HostName)
TextBox2.Text = hostInfo.HostName
' Response.Write(ControlChars.Cr + "Aliases :")
Dim index As Integer
For index = 0 To [alias].Length - 1
Response.Write([alias](index))
Next index
'Response.Write(ControlChars.Cr + "IP address list : ")

For index = 0 To address.Length - 1
Response.Write(address(index))
Next index

Catch e As SocketException
Response.Write("SocketException caught!!!")
Response.Write(("Source : " + e.Source))
Response.Write(("Message : " + e.Message))

Catch e As FormatException
Response.Write("FormatException caught!!!")
Response.Write(("Source : " + e.Source))
Response.Write(("Message : " + e.Message))

Catch e As ArgumentNullException
Response.Write("ArgumentNullException caught!!!")
Response.Write(("Source : " + e.Source))
Response.Write(("Message : " + e.Message))

Catch e As Exception
Response.Write("Exception caught!!!")
Response.Write(("Source : " + e.Source))
Response.Write(("Message : " + e.Message))
End Try
End Sub 'DisplayHostAddress



End Class
shisanjin 2003-12-03
  • 打赏
  • 举报
回复
study
speedyen 2003-12-03
  • 打赏
  • 举报
回复
up
youngby 2003-12-02
  • 打赏
  • 举报
回复
‘首先我們定義一個類,主要用於得到某個IP地址的Service的狀態資訊,並在服務狀態不正常時觸發另一線程得到該系統的詳細資訊。
Imports System.ServiceProcess
Imports System.Xml
Imports System.Threading
Public Class GetStatus
Private IServiceName As String ‘服務的名稱
Private IMachineIP As String ‘IP地址
Private ITable As String ‘在DATESET中的表名
'構造函數
Sub New(ByVal Ip As String, ByVal SvcName As String, ByVal updatetable As String)
IMachineIP = Ip
IServiceName = SvcName
ITable = updatetable
End Sub
‘每個線程所運行的方法,用於得到服務的狀態,如果狀態不正常則觸發另一線程得到該IP的資訊
Sub GetStausF()
Dim ServiceP As New ServiceController() ‘實例化一個ServiceController類
ServiceP.MachineName = IMachineIP
ServiceP.ServiceName = IServiceName
Dim myRow As DataRow
Dim status As String
Dim Run As Boolean = False
myRow = ds.Tables(ITable).NewRow
Try
If ServiceP.Status.ToString <> "Running" Then
status = ServiceP.Status.ToString‘如果狀態不是RUNNING則將狀態賦予字元串變量
Else
Run = True ‘如果狀態為RUNNING,則不做任何事
End If
Catch er As Exception ‘以下處理取得狀態時候發生的異常
status = Left(er.Message, 35)
If InStr(status, "Service Control Manager") = 0 Then
status = "Not installed or open service failed" ‘沒有裝設該服務
ElseIf InStr(er.Message, "Manager") > 0 Then
status = "Can not detected" ‘服務的狀態不可得
End If
End Try
ServiceP.Close() ‘關閉ServiceController實例
‘以下判斷如果狀態不是RUNNING,則記錄該系統,並觸發線程得到它的詳細資訊。
If Not Run Then
myRow("msg") = status
myRow("ip") = IMachineIP
SyncLock GetType(AddRow) ‘為保證多線程情況下,對DataSet只有一個寫操作,鎖定AddRow類
Dim AddRowIns As New AddRow(myRow) '將IP和狀態透過我們自己寫的AddRow類插入DataSet
End SyncLock
‘觸發另一線程取得機器資訊
Dim HostInfo2 As New HostInfo(IMachineIP)
Dim HostThr2 As New Thread(New ThreadStart(AddressOf HostInfo2.sysInfo))
HostThr2.Start()
SyncLock GetType(HostInfoThreadCounter)
HostInfoThreadCounter.counter += 1 ‘啟動線程數加1
End SyncLock
End If
SyncLock GetType(StoppCounter)
StopThr.AddStop()
End SyncLock
End Sub
End Class
‘該類只有一個方法,就是將停止的線程數減1
Class StoppCounter
Sub AddStop()
ThreadCounterStopped = ThreadCounterStopped + 1
End Sub
End Class
‘此類用於將已有的行插入DataSet
Class AddRow
‘第一個構造函數,以構造好的行為輸入參數
Sub New(ByVal row As DataRow)
Try
ds.Tables(0).Rows.Add(row)
Catch ee As Exception

End Try
End Sub
‘第二個構造函數,以機器名用戶名等字元串為參數,更新已有的行
Sub New(ByVal IP As String, ByVal user As String, ByVal hostname As String, ByVal Mac As String, ByVal domain As String, ByVal timeout As Char)
Dim RowTimeOut As DataRow
Try
For Each RowTimeOut In ds.Tables(0).Select("IP='" & IP & "'")
RowTimeOut.Item("LastUID") = user
RowTimeOut.Item("Name") = hostname
RowTimeOut.Item("Mac") = Mac
RowTimeOut.Item("Domain") = domain
RowTimeOut.Item("Timeout") = timeout 'Set timeout flag to this item
Exit For 'just run once
Next
Catch er As Exception

End Try
End Sub
End Class

‘由於篇幅限制,這裏省略了根據IP取得機器資訊的類的代碼。

Imports System.Threading ‘用於支援多線程
Imports System.Xml ‘用於分析XML格式的參數文件
Imports System.Data ‘用於保存結果到資料庫
Module Module1
Public ds As New DataSet()
Public conn1 As SqlClient.SqlConnection ‘資料庫連接
Public ipf As String ‘IP清單檔案名稱
Public dbf As String ‘資料庫資訊文件
Public ThreadCounterStopped As Integer
Public StopThr As New StoppCounter()
Sub Main() ‘程式主程式
Dim machineIP As String
Dim iplistF As New Xml.XmlDocument()
Dim iplist As Xml.XmlNode
Dim ipitem As Xml.XmlNode
Dim DBinfoF As New Xml.XmlDocument()
Dim DBinfo As Xml.XmlNode
Dim LanID As String
Dim i As Integer
Dim timestart As Integer
Dim ThreadCounterStarted As Integer

ThreadCounterStarted = 0
ThreadCounterStopped = 0
Dim server As String
Dim database As String
Dim uid As String
Dim pwd As String
Dim table As String
Dim connstr, connstr1 As String
Dim ServiceName As String
Dim Purgestr As String
Try
DBinfoF.Load(dbf) ‘讀取資料庫資訊文件
Catch nodb As Exception
MsgBox(nodb.Message & "Wrong DB info file name.")
Exit Sub
End Try
Try
iplistF.Load(ipf) ‘讀取IP清單文件
Catch noip As Exception
MsgBox(noip.Message & "Wrong IP list file name.")
Exit Sub
End Try
‘分析資料庫資訊文件
DBinfo = DBinfoF.ChildNodes(0)
server = DBinfo.ChildNodes(0).InnerText
database = DBinfo.ChildNodes(1).InnerText
uid = DBinfo.ChildNodes(2).InnerText
pwd = DBinfo.ChildNodes(3).InnerText
ServiceName = DBinfo.ChildNodes(4).InnerText
table = DBinfo.ChildNodes(4).Attributes(0).Value
‘根據分析所得,構造連接字元串
connstr1 = "server=" & server & ";database=" & database & ";uid=" & uid & ";password=" & pwd
conn1 = New SqlClient.SqlConnection(connstr1) ‘實例化資料庫連接
conn1.Open() ‘打開資料庫連接

Dim sa As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter("select * from " & table, conn1)
Dim combu As New SqlClient.SqlCommandBuilder(sa)
sa.Fill(ds, table) ‘填充DataSet
ds.Clear() ‘清空舊的數據

Dim IPAddress As String
‘分析IP清單文件
iplist = iplistF.ChildNodes(0)
Dim Ai As Integer
Dim ipexcepCount As Integer
Dim ipexcep As Xml.XmlNode
For Each ipitem In iplist.ChildNodes
Dim Excep(2, 83) As Integer
LanID = ipitem.Attributes(0).Value‘得到網路ID
For i = 2 To 254 '從2到254,根據每個網路ID構造IP地址
Ai = 0
‘以下判斷是為了跳過保留地址段
If ipitem.HasChildNodes Then
ipexcepCount = ipitem.ChildNodes.Count
ReDim Excep(2, ipexcepCount - 1)
For Each ipexcep In ipitem.ChildNodes
Excep(0, Ai) = CInt(ipexcep.Attributes(0).Value)
Excep(1, Ai) = CInt(ipexcep.Attributes(1).Value)
Ai = Ai + 1
Next
End If
For Ai = 0 To ipexcepCount - 1
If i >= Excep(0, Ai) And i <= Excep(1, Ai) Then
Console.WriteLine("跳過保留地址: " & LanID & i.ToString)
GoTo SkipIP
End If
Next
machineIP = LanID & i.ToString ‘IP地址
‘以下觸發線程以,得到服務狀態
Dim getSt As New GetStatus(machineIP, ServiceName, table)
Dim GetStThread As New Thread(New ThreadStart(AddressOf getSt.GetStausF))
GetStThread.Start()
ThreadCounterStarted = ThreadCounterStarted + 1‘啟動線程數加1
Console.WriteLine("線程" & machineIP & " 啟動。偵測 " & ServiceName)
‘每啟動100個線程,程式主線程停止15秒,避免太多線程造成記憶體溢出
If (ThreadCounterStarted Mod 100) = 0 Then
Console.WriteLine("等待 .......")
Thread.CurrentThread.Sleep(15000)
GC.Collect() 'force garbage collection to aviod outOfMemory when run with long IP list
End If
SkipIP:
Next
Next
Console.WriteLine("Exiting program ...") '所有線程都已觸發
Finish:
Thread.CurrentThread.Sleep(5000) ‘以下程式等待所有線程結束
GC.Collect()
If ThreadCounterStopped = ThreadCounterStarted And HostInfoThreadCounter.counter = HostInfoThreadCounter.counterSTOP Then‘如果觸發線程等於結束線程

Dim row As Data.DataRow
For Each row In ds.Tables(table).Rows
row.Item("SysTime") = Now
Next
Purgestr = "delete " & table
Dim com1 As New SqlClient.SqlCommand(Purgestr, conn1)
com1.ExecuteNonQuery() ‘刪除舊記錄
sa.InsertCommand = combu.GetInsertCommand
sa.Update(ds, table) ' 將新記錄寫入資料庫
Else
GoTo Finish ' goto finish and wait another 30 seconds
End If
End Sub
youngby 2003-12-02
  • 打赏
  • 举报
回复
// rmac.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "afxsock.h"
#include <iphlpapi.h> //ip helper lib需要最新的MS paltform SDK 或者使用VC7
#include "rmac.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一的应用程序对象

CWinApp theApp;

using namespace std;


#pragma comment ( lib, "ws2_32.lib" )
#pragma comment ( lib, "Iphlpapi.lib" )

void doFunction( int argc, char ** argv )
{
int numberOfHost = 1;
struct hostent *remoteHostent;

//处理命令行参数
if ( argc == 3 )
numberOfHost = atoi( argv[2] );
if ( ( argc >3 ) || ( argc < 2 ) )
{
printf( "RmtHost v0.2 - Get remote HostName /MacAddress\n" );
printf( "by ShotgunLabs ( Shotgun@xici.net )\n\n" );
printf( "Usage :\n\tRmtHost.exe [RemoteIP]\n\n" );
printf( "Example:\n\tRmtHost.exe 192.168.0.3\n" );
printf( "\tRmtHost.exe 192.168.0.3 255\n\n" );
exit( 0 );
}
//初始化SOCKET
WSADATA wsaData;
int iRet = WSAStartup(MAKEWORD(2,1), &wsaData);
if ( iRet != 0 )
{
printf( "WSAStartup Error:%d\n", GetLastError() );
exit( 0 );
}
int nRemoteAddr = inet_addr( argv[1] );
remoteHostent= (struct hostent*)malloc( sizeof(struct hostent ));
struct in_addr sa;
for ( int i = 0; i < numberOfHost; i ++ )
{
//获取远程机器名
sa.s_addr = nRemoteAddr;
printf( "\nIpAddress : %s\n", inet_ntoa( sa ) );
remoteHostent = gethostbyaddr( (char*)&nRemoteAddr,4, AF_INET );
if ( remoteHostent )
printf( "HostName : %s\n",remoteHostent->h_name );
else
printf( "gethostbyaddr Error:%d\n",GetLastError() );
//发送ARP查询包获得远程MAC地址

unsigned char macAddress[6];
ULONG macAddLen = 6;
iRet=SendARP(nRemoteAddr, (unsigned long)NULL,(PULONG)&macAddress, &macAddLen);
if ( iRet == NO_ERROR )
{
printf( "MacAddress: " );
for( int i =0; i<6; i++ )
{
printf( "%.2x", macAddress[i] );
if ( i<5 ) printf( "-" );
}
printf( "\n" );
}
else
printf( "SendARP Error:%d\n", GetLastError());
nRemoteAddr = htonl( ntohl( nRemoteAddr ) + 1 );
}
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误:MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
doFunction(argc,argv);
}

return nRetCode;
}

正文完
zhangxueq 2003-12-02
  • 打赏
  • 举报
回复
楼上的,我是说远程机器的,不是本地的
menuvb 2003-12-02
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/topic/2002/2002164.xml?temp=.898739

http://expert.csdn.net/Expert/topic/2483/2483144.xml?temp=.4093897
zhangxueq 2003-12-02
  • 打赏
  • 举报
回复
请高手帮忙阿,多谢了

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧