因此,我决定包装 Windows API 将是最不混乱的解决方案,并提出以下内容供所有人查看:
首先,我创建了Friend NotInheritable Class
一个名为NativeMethods的私有构造函数(大致相当于 C# 中的静态内部类)和一个名为IPHelper的子类(也是静态内部类) 。这是我放置从 pinvoke.net (源代码)无耻复制的 DllImport 的地方。
Friend NotInheritable Class NativeMethods
Private Sub New()
End Sub
Friend NotInheritable Class IPHelper
Private Sub New()
End Sub
' Possible return values
Friend Const NO_ERROR As Integer = 0
Friend Const ERROR_BAD_NET_NAME As Integer = 67
Friend Const ERROR_BUFFER_OVERFLOW As Integer = 111
Friend Const ERROR_GEN_FAILURE As Integer = 31
Friend Const ERROR_INVALID_PARAMETER As Integer = 87
Friend Const ERROR_INVALID_USER_BUFFER As Integer = 1784
Friend Const ERROR_NOT_FOUND As Integer = 1168
Friend Const ERROR_NOT_SUPPORTED As Integer = 50
' API function declaration.
<DllImport("iphlpapi.dll", SetLastError:=True)>
Friend Shared Function SendARP(
DestIP As UInt32,
SrcIP As UInt32,
pMacAddr() As Byte,
ByRef PhyAddrLen As Int32) As UInt32
End Function
End Class
End Class
现在最重要的是,我编写了一个使用 SendARP 方法的公共类ArpRequest 。
Imports System.Net
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.IO
Imports System.Net.NetworkInformation
Public Class ArpRequest
Private _address As IPAddress
Public Sub New(address As IPAddress)
_address = address
End Sub
''' <summary>
''' Gets the MAC address that belongs to the specified IP address.
''' </summary>
''' <remarks>This uses a native method and should be replaced when a managed alternative becomes available.</remarks>
Public Function GetResponse() As PhysicalAddress
Dim ip As UInteger = BitConverter.ToUInt32(_address.GetAddressBytes(), 0)
Dim mac() As Byte = New Byte(5) {}
Dim ReturnValue As Integer = CInt(NativeMethods.IPHelper.SendARP(CUInt(ip), 0, mac, mac.Length))
If ReturnValue = NativeMethods.IPHelper.NO_ERROR Then
Return New PhysicalAddress(mac)
Else
' TODO: handle various SendARP errors
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa366358(v=vs.85).aspx
Throw New Win32Exception(CInt(ReturnValue))
End If
End Function
End Class
用法很简单(但要注意 Win32Exceptions):
Dim ip = System.Net.IPAddress.Parse("0.0.0.0") ' replace with actual ip
Dim arp = New ArpRequest(ip)
Dim hardwareAddress = arp.GetResponse()