我绝对没有关于C(或任何其他非托管语言)编程的背景知识,但我想在我的.NET应用程序中使用IP Helper API中的GetBestInterface函数。我试图理解如何使用P / invoke调用来调用本机方法,但有许多事情对我来说没有意义(比如托管代码中的类型如何映射到非托管类型)。
在System.Net命名空间中隐藏的某个替代函数是否执行大致相同的操作?或者我可以使用现有的基类结合一些魔法来编写自己的替代方案吗?因为这基本上就像我看来的那样:魔术。就我所知,该方法如何完成它所做的事情没有真正的解释......
修改
我刚刚在System.Net.Sockets.Socket
类上发现了LocalEndPoint属性,我觉得这可能非常有用。根据我的理解,它将代表我进行最佳接口选择,我只需要获得与本地端点对应的NIC。
答案 0 :(得分:1)
好吧我自己把一些东西放在一起,通过捎带框架自己进行界面选择的能力来工作。本质上它只是连接一个套接字,然后使用套接字上的LocalEndPoint属性来获取它正在使用的NIC。可能不是最好的方法,但它对我有用。
使用以下导入语句:
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Net.Sockets
我超级棒的方法:
Private Function GetBestInterfaceManaged(ByVal address As IPAddress, ByVal port As Integer) As NetworkInterface
Dim socket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)
Dim outgoingInterface As NetworkInterface = Nothing
Try
socket.Connect(New IPEndPoint(address, port))
If socket.Connected Then ' find the outgoing NIC
Dim interfaces As List(Of NetworkInterface) = NetworkInterface.GetAllNetworkInterfaces.ToList()
For Each nic As NetworkInterface In interfaces
Dim properties As IPInterfaceProperties = nic.GetIPProperties
For Each unicastAddress In properties.UnicastAddresses
If unicastAddress.Address.Equals(DirectCast(socket.LocalEndPoint, IPEndPoint).Address) Then
outgoingInterface = nic
End If
Next
Next
If outgoingInterface Is Nothing Then
Console.WriteLine("Darn... it didn't work!")
Else
Console.WriteLine("Outgoing interface: {0}", outgoingInterface.Name)
End If
Return outgoingInterface
End If
Catch ex As SocketException
Console.WriteLine(ex.Message)
End Try
Return Nothing
End Function
这样可以解决问题:
Sub Main()
Dim hostEntry As IPHostEntry = Dns.GetHostEntry("www.stackoverflow.com")
Dim NIC As NetworkInterface = GetBestInterfaceManaged(hostEntry.AddressList.First, 80)
' Other code goes down here
End Sub
答案 1 :(得分:1)
我还需要GetBestInterface
,因为我需要一个解决方案,该解决方案在无法到达要探查的远程地址(某些Steven的解决方案会遇到问题)的情况下起作用,并且要与本机应用程序100%兼容移植到C#。
幸运的是,自{{以来,您不必移植GetAdaptersInfo
以及所有相应的IP_ADAPTER_INFO
和子结构的混乱情况,即可找到哪个网络接口具有由GetBestInterface
返回的索引。 3}}。
因此,首先将GetBestInterface
方法移植如下:
[DllImport("iphlpapi")]
private static extern int GetBestInterface(uint dwDestAddr, ref uint pdwBestIfIndex);
然后,编写一个包装器函数,如下所示:
private static NetworkInterface GetBestNetworkInterface(IPAddress remoteAddress)
{
// Get the index of the interface with the best route to the remote address.
uint dwDestAddr = BitConverter.ToUInt32(remoteAddress.GetAddressBytes());
uint dwBestIfIndex = 0;
uint result = GetBestInterface(dwDestAddr, ref dwBestIfIndex);
if (result != 0)
throw new NetworkInformationException((int)result);
// Find a matching .NET interface object with the given index.
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
if (networkInterface.GetIPProperties().GetIPv4Properties().Index == dwBestIfIndex)
return networkInterface;
throw new InvalidOperationException($"Could not find best interface for {remoteAddress}.");
}
然后您可以像这样简单地调用方法-并且不要忘记无法访问的主机现在也可以工作:
NetworkInterface bestNetworkInterface = GetBestNetworkInterface(IPAddress.Parse("8.8.8.8"));