Как получить IP-адрес сервера, на котором запущено мое приложение C#?
Я использую сервер и хочу показать свой собственный IP-адрес.
Каков синтаксис для получения собственного (если возможно, внешнего) IP-адреса компьютера?
Кто-то написал следующий код.
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily.ToString() == "InterNetwork")
{
localIP = ip.ToString();
}
}
return localIP;
Однако я вообще не доверяю автору и не понимаю этот код. Есть ли лучший способ сделать это?
27 ответов
Нет, это в значительной степени лучший способ сделать это. Поскольку у машины может быть несколько IP-адресов, вам нужно выполнить итерацию их коллекции, чтобы найти правильный.
Изменить: Единственное, что я хотел бы изменить, это изменить это:
if (ip.AddressFamily.ToString() == "InterNetwork")
к этому:
if (ip.AddressFamily == AddressFamily.InterNetwork)
Там нет необходимости ToString
перечисление для сравнения.
Единственный способ узнать ваш общедоступный IP-адрес - попросить кого-то еще рассказать вам; этот код может помочь вам:
public string GetPublicIP()
{
String direction = "";
WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
using (WebResponse response = request.GetResponse())
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
direction = stream.ReadToEnd();
}
//Search for the ip in the html
int first = direction.IndexOf("Address: ") + 9;
int last = direction.LastIndexOf("</body>");
direction = direction.Substring(first, last - first);
return direction;
}
Чище и все в одном решении:D
//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
Если вы не можете рассчитывать на получение своего IP-адреса от DNS-сервера (что случилось со мной), вы можете использовать следующий подход:
Пространство имен System.Net.NetworkInformation содержит класс NetworkInterface, который имеет статический метод GetAllNetworkInterfaces.
Этот метод вернет все "сетевые интерфейсы" на вашем компьютере, и их, как правило, довольно много, даже если на вашем компьютере установлено только адаптер беспроводной сети и / или адаптер Ethernet. Все эти сетевые интерфейсы имеют действительные IP-адреса для вашего локального компьютера, хотя, вероятно, вам нужен только один.
Если вы ищете один IP-адрес, вам нужно будет отфильтровать список, пока вы не сможете определить правильный адрес. Возможно, вам нужно будет поэкспериментировать, но у меня был успех при следующем подходе:
- Отфильтруйте все неактивные NetworkInterfaces, проверив
OperationalStatus == OperationalStatus.Up
, Это исключит ваш физический адаптер Ethernet, например, если у вас нет подключенного сетевого кабеля.
Для каждого NetworkInterface вы можете получить объект IPInterfaceProperties с помощью метода GetIPProperties, а из объекта IPInterfaceProperties вы можете получить доступ к свойству UnicastAddresses для списка объектов UnicastIPAddressInformation.
- Отфильтруйте нежелательные одноадресные адреса, проверив
DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
- Отфильтруйте "виртуальные" адреса, проверив
AddressPreferredLifetime != UInt32.MaxValue
,
В этот момент я беру адрес первого (если есть) одноадресного адреса, который соответствует всем этим фильтрам.
РЕДАКТИРОВАТЬ:
[пересмотренный код от 16 мая 2018 года, включающий условия, упомянутые в тексте выше, для состояния обнаружения дублированного адреса и предпочтительного времени жизни]
В приведенном ниже примере демонстрируется фильтрация на основе рабочего состояния, семейства адресов, за исключением адреса обратной связи (127.0.0.1), состояния обнаружения дублированного адреса и предпочтительного времени жизни.
static IEnumerable<IPAddress> GetLocalIpAddresses()
{
// Get the list of network interfaces for the local computer.
var adapters = NetworkInterface.GetAllNetworkInterfaces();
// Return the list of local IPv4 addresses excluding the local
// host, disconnected, and virtual addresses.
return (from adapter in adapters
let properties = adapter.GetIPProperties()
from address in properties.UnicastAddresses
where adapter.OperationalStatus == OperationalStatus.Up &&
address.Address.AddressFamily == AddressFamily.InterNetwork &&
!address.Equals(IPAddress.Loopback) &&
address.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred &&
address.AddressPreferredLifetime != UInt32.MaxValue
select address.Address);
}
WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");
using System.Net;
string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());
Только что проверил это на моей машине, и это работает.
Если вы хотите избежать использования DNS:
List<IPAddress> ipList = new List<IPAddress>();
foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
{
foreach (var address in netInterface.GetIPProperties().UnicastAddresses)
{
if (address.Address.AddressFamily == AddressFamily.InterNetwork)
{
Console.WriteLine("found IP " + address.Address.ToString());
ipList.Add(address.Address);
}
}
}
Не полагайтесь на InterNetwork все время, потому что вы можете иметь более одного устройства, которое также использует IP4, что может испортить результаты при получении вашего IP. Теперь, если вы хотите, вы можете просто скопировать это и, пожалуйста, просмотрите или обновите его так, как считаете нужным.
Сначала я получаю адрес маршрутизатора (шлюза). Если возвращается, что я подключен к шлюзу (что означает, что он не подключен напрямую к беспроводной модеме или нет), тогда у нас есть адрес нашего шлюза в качестве IP-адреса, иначе мы указываем нулевой указатель на IP-адрес.,
Затем нам нужно получить список IP-адресов компьютера. Здесь все не так сложно, потому что маршрутизаторы (все маршрутизаторы) используют 4 байта (...). Первые три являются наиболее важными, потому что любой компьютер, подключенный к нему, будет иметь IP4-адрес, соответствующий первым трем байтам. Пример: 192.168.0.1 является стандартным для IP-адреса маршрутизатора по умолчанию, если он не был изменен его администратором. "192.168.0" или что бы они ни были, это то, что нам нужно, чтобы соответствовать. И это все, что я сделал в функции IsAddressOfGateway. Причина соответствия длины заключается в том, что не все адреса (которые предназначены только для компьютера) имеют длину 4 байта. Если вы введете netstat в cmd, вы обнаружите, что это правда. Так что у вас есть это. Да, чтобы получить то, что вы ищете, нужно немного больше работы. Процесс устранения. И ради бога, не находите адрес, отправляя эхо-запрос, что занимает много времени, потому что сначала вы отправляете адрес для проверки, а затем он должен отправить результат обратно. Нет, работайте напрямую с классами.Net, которые имеют отношение к вашей системной среде, и вы получите ответы, которые вы ищете, когда это касается исключительно вашего компьютера.
Теперь, если вы напрямую подключены к своему модему, процесс почти такой же, потому что модем является вашим шлюзом, но подмаски не то же самое, потому что вы получаете информацию непосредственно с вашего DNS-сервера через модем и не маскируетесь маршрутизатором, обслуживающим Интернет, хотя вы все еще можете использовать тот же код, потому что последний байт IP-адреса, назначенного модему, равен 1. Поэтому, если IP-адрес, отправленный с модема, который изменяет значение, равен 111.111.111.1', вы получите 111.111.111.(Некоторые значение байта). Имейте в виду, что нам нужно найти информацию о шлюзе, потому что есть больше устройств, которые имеют дело с подключением к Интернету, чем ваш маршрутизатор и модем.
Теперь вы понимаете, почему вы НЕ меняете первые два байта вашего маршрутизатора 192 и 168. Они строго различаются только для маршрутизаторов, а не для использования в Интернете, иначе у нас возникнет серьезная проблема с протоколом IP и двойным пингом, что приведет к сбоям в работе компьютера. Представьте, что вам назначен IP-адрес маршрутизатора 192.168.44.103, и вы также щелкаете по сайту с таким IP-адресом. О, МОЙ БОГ! Ваш компьютер не будет знать, что пинговать. Сбой прямо там. Чтобы избежать этой проблемы, назначаются только маршрутизаторы, а не для использования в Интернете. Поэтому оставьте первые два байта маршрутизатора в покое.
static IPAddress FindLanAddress()
{
IPAddress gateway = FindGetGatewayAddress();
if (gateway == null)
return null;
IPAddress[] pIPAddress = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress address in pIPAddress) {
if (IsAddressOfGateway(address, gateway))
return address;
return null;
}
static bool IsAddressOfGateway(IPAddress address, IPAddress gateway)
{
if (address != null && gateway != null)
return IsAddressOfGateway(address.GetAddressBytes(),gateway.GetAddressBytes());
return false;
}
static bool IsAddressOfGateway(byte[] address, byte[] gateway)
{
if (address != null && gateway != null)
{
int gwLen = gateway.Length;
if (gwLen > 0)
{
if (address.Length == gateway.Length)
{
--gwLen;
int counter = 0;
for (int i = 0; i < gwLen; i++)
{
if (address[i] == gateway[i])
++counter;
}
return (counter == gwLen);
}
}
}
return false;
}
static IPAddress FindGetGatewayAddress()
{
IPGlobalProperties ipGlobProps = IPGlobalProperties.GetIPGlobalProperties();
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
IPInterfaceProperties ipInfProps = ni.GetIPProperties();
foreach (GatewayIPAddressInformation gi in ipInfProps.GatewayAddresses)
return gi.Address;
}
return null;
}
Я просто подумал, что добавлю свою собственную, однострочную (хотя уже есть много других полезных ответов).
string ipAddress = new WebClient().DownloadString("http://icanhazip.com");
Для получения текущего общедоступного IP-адреса все, что вам нужно сделать, это создать страницу ASPX со следующей строкой в событии загрузки страницы:
Response.Write(HttpContext.Current.Request.UserHostAddress.ToString());
Если вы работаете в интрасети, вы сможете получить IP-адрес локального компьютера, а если нет, вы получите внешний IP-адрес с помощью этого: Web:
//this will bring the IP for the current machine on browser
System.Web.HttpContext.Current.Request.UserHostAddress
Рабочий стол:
//This one will bring all local IPs for the desired namespace
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
namespace NKUtilities
{
using System;
using System.Net;
using System.Net.Sockets;
public class DNSUtility
{
public static int Main(string [] args)
{
string strHostName = "";
try {
if(args.Length == 0)
{
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine ("Local Machine's Host Name: " + strHostName);
}
else
{
// Otherwise, get the IP address of the host provided on the command line.
strHostName = args[0];
}
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry (strHostName);
IPAddress [] addr = ipEntry.AddressList;
for(int i = 0; i < addr.Length; i++)
{
Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
}
return 0;
}
catch(SocketException se)
{
Console.WriteLine("{0} ({1})", se.Message, strHostName);
return -1;
}
catch(Exception ex)
{
Console.WriteLine("Error: {0}.", ex.Message);
return -1;
}
}
}
}
Смотрите здесь для деталей.
Вы должны помнить, что ваш компьютер может иметь более одного IP-адреса (на самом деле это всегда так), поэтому какой вам нужен.
Попробуй это:
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
String MyIp = localIPs[0].ToString();
Вопрос не говорит ASP.NET MVC, но я все равно оставляю это здесь:
Request.UserHostAddress
Может быть, по внешнему IP вы можете рассмотреть (если вы находитесь в контексте веб-сервера) использование этого
Request.ServerVariables["LOCAL_ADDR"];
Я задавал тот же вопрос, что и вы, и нашел его в этой статье stackru.
Это сработало для меня.
Чтобы найти список IP-адресов, я использовал это решение
public static IEnumerable<string> GetAddresses()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}
Но мне лично нравится ниже решение, чтобы получить локальный действительный IP-адрес
public static IPAddress GetIPAddress(string hostName)
{
Ping ping = new Ping();
var replay = ping.Send(hostName);
if (replay.Status == IPStatus.Success)
{
return replay.Address;
}
return null;
}
public static void Main()
{
Console.WriteLine("Local IP Address: " + GetIPAddress(Dns.GetHostName()));
Console.WriteLine("Google IP:" + GetIPAddress("google.com");
Console.ReadLine();
}
Решение LINQ:
Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).FirstOrDefault() ?? ""
Еще один способ получить ваш публичный IP-адрес - использовать OpenDNS. resolve1.opendns.com
сервер с myip.opendns.com
как запрос
В командной строке это:
nslookup myip.opendns.com resolver1.opendns.com
Или в C#, используя DNSClient nuget:
var lookup = new LookupClient(new IPAddress(new byte[] { 208, 67, 222, 222 }));
var result = lookup.Query("myip.opendns.com", QueryType.ANY);
Это немного чище, чем попадание на конечные точки http и анализ ответов.
Это работает для меня... и должно быть быстрее в большинстве случаев (если не во всех), чем запросы к DNS-серверу. Благодаря ученику доктора Вилли ( здесь).
// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
List<NetworkInterface> candidates = new List<NetworkInterface>();
if (NetworkInterface.GetIsNetworkAvailable())
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (
NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
candidates.Add(ni);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
// Accoring to our tech, the main NetworkInterface should have a Gateway
// and it should be the ony one with a gateway.
if (candidates.Count > 1)
{
for (int n = candidates.Count - 1; n >= 0; n--)
{
if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
{
candidates.RemoveAt(n);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
}
// Fallback to try by getting my ipAdress from the dns
IPAddress myMainIpAdress = null;
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
{
myMainIpAdress = ip;
break;
}
}
if (myMainIpAdress != null)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.Address.Equals(myMainIpAdress))
{
return ni;
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackru.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4, AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.GetPhysicalAddress().Equals(mac))
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
{
if (ai.Address.AddressFamily == addressFamily)
{
return ai.Address;
}
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
NetworkInterface ni = GetMainNetworkInterface();
IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
if (ipAddress == null) // could it be possible ?
{
ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
}
return ipAddress;
}
// ******************************************************************
Так же, как ссылка, это полный код класса, в котором я его определил:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace TcpMonitor
{
/*
Usage:
var cons = TcpHelper.GetAllTCPConnections();
foreach (TcpHelper.MIB_TCPROW_OWNER_PID c in cons) ...
*/
public class NetHelper
{
[DllImport("iphlpapi.dll", SetLastError = true)]
static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = 0);
public enum UDP_TABLE_CLASS
{
UDP_TABLE_BASIC,
UDP_TABLE_OWNER_PID,
UDP_TABLE_OWNER_MODULE
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDPROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPROW_OWNER_PID
{
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDP6TABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDP6ROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDP6ROW_OWNER_PID
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] localAddr;
public uint localScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr, localScopeId); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
}
public static List<MIB_UDPROW_OWNER_PID> GetAllUDPConnections()
{
return GetUDPConnections<MIB_UDPROW_OWNER_PID, MIB_UDPTABLE_OWNER_PID> (AF_INET);
}
public static List<MIB_UDP6ROW_OWNER_PID> GetAllUDPv6Connections()
{
return GetUDPConnections<MIB_UDP6ROW_OWNER_PID, MIB_UDP6TABLE_OWNER_PID>(AF_INET6);
}
private static List<IPR> GetUDPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
{
List<IPR> result = null;
IPR[] tableRows = null;
int buffSize = 0;
var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");
// how much memory do we need?
uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
IntPtr udpTablePtr = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedUdpTable(udpTablePtr, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
if (ret != 0)
return new List<IPR>();
// get the number of entries in the table
IPT table = (IPT)Marshal.PtrToStructure(udpTablePtr, typeof(IPT));
int rowStructSize = Marshal.SizeOf(typeof(IPR));
uint numEntries = (uint)dwNumEntriesField.GetValue(table);
// buffer we will be returning
tableRows = new IPR[numEntries];
IntPtr rowPtr = (IntPtr)((long)udpTablePtr + 4);
for (int i = 0; i < numEntries; i++)
{
IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
tableRows[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + rowStructSize); // next entry
}
}
finally
{
result = tableRows?.ToList() ?? new List<IPR>();
// Free the Memory
Marshal.FreeHGlobal(udpTablePtr);
}
return result;
}
[DllImport("iphlpapi.dll", SetLastError = true)]
static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = 0);
public enum MIB_TCP_STATE
{
MIB_TCP_STATE_CLOSED = 1,
MIB_TCP_STATE_LISTEN = 2,
MIB_TCP_STATE_SYN_SENT = 3,
MIB_TCP_STATE_SYN_RCVD = 4,
MIB_TCP_STATE_ESTAB = 5,
MIB_TCP_STATE_FIN_WAIT1 = 6,
MIB_TCP_STATE_FIN_WAIT2 = 7,
MIB_TCP_STATE_CLOSE_WAIT = 8,
MIB_TCP_STATE_CLOSING = 9,
MIB_TCP_STATE_LAST_ACK = 10,
MIB_TCP_STATE_TIME_WAIT = 11,
MIB_TCP_STATE_DELETE_TCB = 12
}
public enum TCP_TABLE_CLASS
{
TCP_TABLE_BASIC_LISTENER,
TCP_TABLE_BASIC_CONNECTIONS,
TCP_TABLE_BASIC_ALL,
TCP_TABLE_OWNER_PID_LISTENER,
TCP_TABLE_OWNER_PID_CONNECTIONS,
TCP_TABLE_OWNER_PID_ALL,
TCP_TABLE_OWNER_MODULE_LISTENER,
TCP_TABLE_OWNER_MODULE_CONNECTIONS,
TCP_TABLE_OWNER_MODULE_ALL
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_TCPROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCP6TABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_TCP6ROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW_OWNER_PID
{
public uint state;
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint remoteAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] remotePort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr); }
}
public ushort LocalPort
{
get
{
return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0);
}
}
public IPAddress RemoteAddress
{
get { return new IPAddress(remoteAddr); }
}
public ushort RemotePort
{
get
{
return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0);
}
}
public MIB_TCP_STATE State
{
get { return (MIB_TCP_STATE)state; }
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCP6ROW_OWNER_PID
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] localAddr;
public uint localScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] remoteAddr;
public uint remoteScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] remotePort;
public uint state;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public long LocalScopeId
{
get { return localScopeId; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr, LocalScopeId); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
public long RemoteScopeId
{
get { return remoteScopeId; }
}
public IPAddress RemoteAddress
{
get { return new IPAddress(remoteAddr, RemoteScopeId); }
}
public ushort RemotePort
{
get { return BitConverter.ToUInt16(remotePort.Take(2).Reverse().ToArray(), 0); }
}
public MIB_TCP_STATE State
{
get { return (MIB_TCP_STATE)state; }
}
}
public const int AF_INET = 2; // IP_v4 = System.Net.Sockets.AddressFamily.InterNetwork
public const int AF_INET6 = 23; // IP_v6 = System.Net.Sockets.AddressFamily.InterNetworkV6
public static Task<List<MIB_TCPROW_OWNER_PID>> GetAllTCPConnectionsAsync()
{
return Task.Run(() => GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET));
}
public static List<MIB_TCPROW_OWNER_PID> GetAllTCPConnections()
{
return GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET);
}
public static Task<List<MIB_TCP6ROW_OWNER_PID>> GetAllTCPv6ConnectionsAsync()
{
return Task.Run(()=>GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6));
}
public static List<MIB_TCP6ROW_OWNER_PID> GetAllTCPv6Connections()
{
return GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6);
}
private static List<IPR> GetTCPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
{
List<IPR> result = null;
IPR[] tableRows = null;
int buffSize = 0;
var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");
// how much memory do we need?
uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
if (ret != 0)
return new List<IPR>();
// get the number of entries in the table
IPT table = (IPT)Marshal.PtrToStructure(tcpTablePtr, typeof(IPT));
int rowStructSize = Marshal.SizeOf(typeof(IPR));
uint numEntries = (uint)dwNumEntriesField.GetValue(table);
// buffer we will be returning
tableRows = new IPR[numEntries];
IntPtr rowPtr = (IntPtr)((long)tcpTablePtr + 4);
for (int i = 0; i < numEntries; i++)
{
IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
tableRows[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + rowStructSize); // next entry
}
}
finally
{
result = tableRows?.ToList() ?? new List<IPR>();
// Free the Memory
Marshal.FreeHGlobal(tcpTablePtr);
}
return result;
}
public static string GetTcpStateName(MIB_TCP_STATE state)
{
switch (state)
{
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSED:
return "Closed";
case MIB_TCP_STATE.MIB_TCP_STATE_LISTEN:
return "Listen";
case MIB_TCP_STATE.MIB_TCP_STATE_SYN_SENT:
return "SynSent";
case MIB_TCP_STATE.MIB_TCP_STATE_SYN_RCVD:
return "SynReceived";
case MIB_TCP_STATE.MIB_TCP_STATE_ESTAB:
return "Established";
case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT1:
return "FinWait 1";
case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT2:
return "FinWait 2";
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSE_WAIT:
return "CloseWait";
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSING:
return "Closing";
case MIB_TCP_STATE.MIB_TCP_STATE_LAST_ACK:
return "LastAck";
case MIB_TCP_STATE.MIB_TCP_STATE_TIME_WAIT:
return "TimeWait";
case MIB_TCP_STATE.MIB_TCP_STATE_DELETE_TCB:
return "DeleteTCB";
default:
return ((int)state).ToString();
}
}
private static readonly ConcurrentDictionary<string, string> DicOfIpToHostName = new ConcurrentDictionary<string, string>();
public const string UnknownHostName = "Unknown";
// ******************************************************************
public static string GetHostName(IPAddress ipAddress)
{
return GetHostName(ipAddress.ToString());
}
// ******************************************************************
public static string GetHostName(string ipAddress)
{
string hostName = null;
if (!DicOfIpToHostName.TryGetValue(ipAddress, out hostName))
{
try
{
if (ipAddress == "0.0.0.0" || ipAddress == "::")
{
hostName = ipAddress;
}
else
{
hostName = Dns.GetHostEntry(ipAddress).HostName;
}
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
hostName = UnknownHostName;
}
DicOfIpToHostName[ipAddress] = hostName;
}
return hostName;
}
// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
List<NetworkInterface> candidates = new List<NetworkInterface>();
if (NetworkInterface.GetIsNetworkAvailable())
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (
NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
candidates.Add(ni);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
// Accoring to our tech, the main NetworkInterface should have a Gateway
// and it should be the ony one with a gateway.
if (candidates.Count > 1)
{
for (int n = candidates.Count - 1; n >= 0; n--)
{
if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
{
candidates.RemoveAt(n);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
}
// Fallback to try by getting my ipAdress from the dns
IPAddress myMainIpAdress = null;
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
{
myMainIpAdress = ip;
break;
}
}
if (myMainIpAdress != null)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.Address.Equals(myMainIpAdress))
{
return ni;
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackru.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4, AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.GetPhysicalAddress().Equals(mac))
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
{
if (ai.Address.AddressFamily == addressFamily)
{
return ai.Address;
}
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
NetworkInterface ni = GetMainNetworkInterface();
IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
if (ipAddress == null) // could it be possible ?
{
ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
}
return ipAddress;
}
// ******************************************************************
public static bool IsBroadcastAddress(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
return ipAddress.GetAddressBytes()[3] == 255;
}
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return false; // NO broadcast in IPv6
}
return false;
}
// ******************************************************************
public static bool IsMulticastAddress(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
// Source: https://technet.microsoft.com/en-us/library/cc772041(v=ws.10).aspx
return ipAddress.GetAddressBytes()[0] >= 224 && ipAddress.GetAddressBytes()[0] <= 239;
}
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return ipAddress.IsIPv6Multicast;
}
return false;
}
// ******************************************************************
}
}
Вот как я это решил. я знаю, если у вас есть несколько физических интерфейсов, это может не выбрать именно то, что вы хотите.
private string FetchIP()
{
//Get all IP registered
List<string> IPList = new List<string>();
IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
IPList.Add(ip.ToString());
}
}
//Find the first IP which is not only local
foreach (string a in IPList)
{
Ping p = new Ping();
string[] b = a.Split('.');
string ip2 = b[0] + "." + b[1] + "." + b[2] + ".1";
PingReply t = p.Send(ip2);
p.Dispose();
if (t.Status == IPStatus.Success && ip2 != a)
{
return a;
}
}
return null;
}
namespace NKUtilities
{
using System;
using System.Net;
public class DNSUtility
{
public static int Main (string [] args)
{
String strHostName = new String ("");
if (args.Length == 0)
{
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName ();
Console.WriteLine ("Local Machine's Host Name: " + strHostName);
}
else
{
strHostName = args[0];
}
// Then using host name, get the IP address list..
IPHostEntry ipEntry = DNS.GetHostByName (strHostName);
IPAddress [] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
Console.WriteLine ("IP Address {0}: {1} ", i, addr[i].ToString ());
}
return 0;
}
}
}
Получить все IP-адреса в виде строк, используя LINQ:
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
...
string[] allIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
.SelectMany(c=>c.GetIPProperties().UnicastAddresses
.Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork)
.Select(d=>d.Address.ToString())
).ToArray();
ФИЛЬТРОВАТЬ ЧАСТНЫХ...
Сначала определите метод расширения IsPrivate()
:
public static class IPAddressExtensions
{
// Collection of private CIDRs (IpAddress/Mask)
private static Tuple<int, int>[] _privateCidrs = new []{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}
.Select(c=>Tuple.Create(BitConverter.ToInt32(IPAddress
.Parse(c.Split('/')[0]).GetAddressBytes(), 0)
, IPAddress.HostToNetworkOrder(-1 << (32-int.Parse(c.Split('/')[1])))))
.ToArray();
public static bool IsPrivate(this IPAddress ipAddress)
{
int ip = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0);
return _privateCidrs.Any(cidr=>(ip & cidr.Item2)==(cidr.Item1 & cidr.Item2));
}
}
... а затем использовать его для фильтрации частных IP-адресов:
string[] publicIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
.SelectMany(c=>c.GetIPProperties().UnicastAddresses
.Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork
&& !d.Address.IsPrivate() // Filter out private ones
)
.Select(d=>d.Address.ToString())
).ToArray();
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
Простая строка кода, которая возвращает первый внутренний IPV4-адрес или ноль, если таковых нет. Добавлен в качестве комментария выше, но может быть полезен для кого-то (некоторые решения выше возвращают несколько адресов, которые нуждаются в дальнейшей фильтрации).
Также легко вернуть loopback вместо null, я думаю, с помощью:
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );
using System;
using System.Net;
namespace IPADDRESS
{
class Program
{
static void Main(string[] args)
{
String strHostName = string.Empty;
if (args.Length == 0)
{
/* First get the host name of local machine.*/
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
}
else
{
strHostName = args[0];
}
/* Then using host name, get the IP address list..*/
IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
}
Console.ReadLine();
}
}
}
И это для получения всех локальных IP-адресов в формате CSV в VB.NET
Imports System.Net
Imports System.Net.Sockets
Function GetIPAddress() As String
Dim ipList As List(Of String) = New List(Of String)
Dim host As IPHostEntry
Dim localIP As String = "?"
host = Dns.GetHostEntry(Dns.GetHostName())
For Each ip As IPAddress In host.AddressList
If ip.AddressFamily = AddressFamily.InterNetwork Then
localIP = ip.ToString()
ipList.Add(localIP)
End If
Next
Dim ret As String = String.Join(",", ipList.ToArray)
Return ret
End Function
private static string GetLocalIpAdresse()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach(var ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception ("No network adapters with an IPv4 address in the system");
}
Чтобы получить удаленный IP-адрес как можно быстрее. Вы должны использовать загрузчик или создать сервер на вашем компьютере.
Недостатки использования этого простого кода: (что рекомендуется) заключается в том, что для получения удаленного IP-адреса потребуется 3-5 секунд, поскольку при инициализации WebClient всегда требуется 3-5 секунд для проверки настроек прокси-сервера.
public static string GetIP()
{
string externalIP = "";
externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/");
externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
.Matches(externalIP)[0].ToString();
return externalIP;
}
Вот как я это исправил.. (первый раз все еще занимает 3-5 секунд), но после этого он всегда получит ваш удаленный IP-адрес через 0-2 секунды, в зависимости от вашего соединения.
public static WebClient webclient = new WebClient();
public static string GetIP()
{
string externalIP = "";
externalIP = webclient.DownloadString("http://checkip.dyndns.org/");
externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
.Matches(externalIP)[0].ToString();
return externalIP;
}