Определение активного сетевого интерфейса
В приложении.NET как определить, какой сетевой интерфейс используется для связи с данным IP-адресом?
Я работаю на рабочих станциях с несколькими сетевыми интерфейсами, IPv4 и v6, и мне нужно получить адрес "правильного" интерфейса, используемого для трафика на данный сервер баз данных.
6 ответов
Самый простой способ будет:
UdpClient u = new UdpClient(remoteAddress, 1);
IPAddress localAddr = ((IPEndPoint)u.Client.LocalEndPoint).Address;
Теперь, если вам нужен объект NetworkInterface, вы делаете что-то вроде:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
IPInterfaceProperties ipProps = nic.GetIPProperties();
// check if localAddr is in ipProps.UnicastAddresses
}
Другой вариант - использовать P/Invoke и вызвать GetBestInterface() для получения индекса интерфейса, а затем снова выполнить цикл по всем сетевым интерфейсам. Как и прежде, вам придется копаться GetIPProperties()
чтобы добраться до IPv4InterfaceProperties.Index
имущество).
Ни один из них на самом деле не даст оператору информацию, которую он ищет - он хочет знать, какой интерфейс будет использоваться для достижения определенного пункта назначения. Один из способов сделать то, что вы хотите, - это выполнить оболочку для команды route с помощью класса System.Diagnostics.Process, а затем просмотреть результаты на экране. route PRINT (destination IP)
даст вам что-то полезное. Возможно, это не самое лучшее решение, но я могу дать вам только одно.
Информация, которую вы ищете, будет в WMI.
Этот пример использования WMI может помочь вам в большей части:
using System.Management;
string query = "SELECT * FROM Win32_NetworkAdapterConfiguration";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();// Every record in this collection is a network interface
foreach (ManagementObject mo in moCollection)
{
// Do what you need to here....
}
Класс Win32_NetworkAdapterConfiguration предоставит вам информацию о конфигурации ваших адаптеров, например, IP-адреса и т. Д.
Вы также можете запросить класс Win32_NetworkAdapter, чтобы выяснить "статический" для каждого адаптера (максимальная скорость, производитель и т. Д.)
Просто чтобы дать полную картину: другой подход будет использовать Socket.IOControl( SIO_ROUTING_INTERFACE_QUERY, ... )
ConferenceXP включает в себя довольно всеобъемлющую функцию, обертывающую это, работает с IPv4/6 и многоадресными адресами: https://github.com/conferencexp/conferencexp/blob/master/MSR.LST.Net.Rtp/NetworkingBasics/utility.cs#L84
По крайней мере, вы можете начать с этого, давая вам все адреса из DNS для локальной машины.
IPHostEntry hostEntry = Dns.GetHostEntry(Environment.MachineName);
foreach (System.Net.IPAddress address in hostEntry.AddressList)
{
Console.WriteLine(address);
}
это старая тема, но сегодня я ищу ее, но, думаю, найду лучший ответ.
/// <summary>
/// Get ifIndex of ip (ip address to connect)
/// </summary>
/// <param name="ip">IP Address that want to connect</param>
/// <param name="description">Lan card description</param>
/// <param name="ifIndex">interface index</param>
/// <param name="ifAddress">IP Address of Lan Interface</param>
private static void CheckInterface(string ip, out string description, out int ifIndex, out IPAddress ifAddress)
{
description = "";
ifIndex = -1;
ifAddress = IPAddress.Any;
var myIp = IPAddress.Parse(ip);
if (!NetworkInterface.GetIsNetworkAvailable()) return;
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
{
if (!adapter.SupportsMulticast) continue;
if (adapter.OperationalStatus != OperationalStatus.Up) continue;
var properties = adapter.GetIPProperties();
if (!properties.MulticastAddresses.Any()) continue;
var p = properties.GetIPv4Properties();
if (p == null) continue;
foreach (var ipInfo in properties.UnicastAddresses)
{
if (ipInfo.Address.AddressFamily == AddressFamily.InterNetwork)
{
//Console.WriteLine("Address:{0} == {1}", ipInfo.Address, myIp);
var adpIp = ipInfo.Address.GetAddressBytes();
var cmpIp = myIp.GetAddressBytes();
if ((adpIp[0] == cmpIp[0]) && (adpIp[1] == cmpIp[1]) && (adpIp[2] == cmpIp[2]))
{
description = adapter.Description;
ifIndex = p.Index;
ifAddress = ipInfo.Address;
return;
//Console.WriteLine("Name {0} ifIndex {1}", adapter.Description, p.Index);
}
}
}
}
}
Сегодня у меня работает! (когда ifIndex равен -1, интерфейс не найден)