【问题标题】:Managed alternative for GetBestInterface?GetBestInterface 的托管替代方案?
【发布时间】:2012-04-27 23:58:30
【问题描述】:

我完全没有使用 C(或任何其他非托管语言)编程的背景,但我想在我的 .NET 应用程序中使用 IP Helper API 中的 GetBestInterface 函数。我试图了解如何使用 P/invoke 调用来调用本机方法,但有很多事情对我来说没有意义(例如托管代码中的类型如何映射到非托管类型)。

是否有隐藏在 System.Net 命名空间中某处的替代函数可以做大致相同的事情?或者我可以使用现有的基类结合一些魔法来编写自己的替代方案吗?因为在我看来,这基本上就是:魔法。据我所知,该方法如何完成它的工作并没有真正的解释......

编辑

我刚刚在 System.Net.Sockets.Socket 类上发现了 LocalEndPoint 属性,我认为它在这方面可能非常有用。据我了解,它将代表我进行最佳接口选择,我只需要获取与本地端点对应的 NIC。

【问题讨论】:

标签: vb.net native-code iphelper


【解决方案1】:

我还需要GetBestInterface,因为我需要一个解决方案,该解决方案可以在无法访问要探测的远程地址时工作(Steven 的解决方案会遇到问题),并且与我要移植到的本机应用程序 100% 兼容C#。

幸运的是,您不必移植GetAdaptersInfo 和所有相应的IP_ADAPTER_INFO 和子结构杂乱,以查找哪个网络接口具有GetBestInterface 返回的索引,因为.NET can retrieve that index from interfaces too 已经存在。

所以,首先移植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"));

【讨论】:

    【解决方案2】:

    好的,我自己整理了一些东西,通过捎带框架自行选择界面的能力来工作。本质上它只是连接一个套接字,然后使用套接字上的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2020-11-01
      • 1970-01-01
      相关资源
      最近更新 更多