首页 文章

如何获取运行我的C#应用程序的服务器的IP地址?

提问于
浏览
358

我正在运行服务器,我想显示自己的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;

但是,我一般不信任作者,我不理解这段代码 . 有没有更好的方法呢?

25 回答

  • 1

    了解您的公共知识产权的唯一方法是请别人告诉您;此代码可以帮助您:

    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;
    }
    
  • 2

    清洁和一体化解决方案:D

    //This returns the first IP4 address or null
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
    
  • 1

    这是为了在VB.NET中以csv格式获取所有本地IP

    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
    
  • 1

    不,这几乎是最好的方法 . 由于一台机器可能有多个IP地址,您需要迭代它们的集合以找到合适的IP地址 .

    Edit: 我唯一要改变的就是改变这个:

    if (ip.AddressFamily.ToString() == "InterNetwork")
    

    对此:

    if (ip.AddressFamily == AddressFamily.InterNetwork)
    

    没有必要 ToString 枚举用于比较 .

  • 17

    如果你不能依赖从DNS服务器获取你的IP地址(这发生在我身上),你可以使用以下方法:

    System.Net.NetworkInformation命名空间包含NetworkInterface class,其具有静态GetAllNetworkInterfaces method .

    此方法将返回您计算机上的所有“网络接口”,即使您的计算机上只安装了无线适配器和/或以太网适配器硬件,也通常会有很多“网络接口” . 所有这些网络接口都具有本地计算机的有效IP地址,尽管您可能只需要一个 .

    如果您正在寻找一个IP地址,那么您需要过滤下来的列表,直到您找到正确的地址 . 您可能需要做一些实验,但我使用以下方法取得了成功:

    • 通过检查 OperationalStatus == OperationalStatus.Up 过滤掉所有处于非活动状态的NetworkInterface . 例如,如果您没有插入网络电缆,这将排除您的物理以太网适配器 .

    对于每个NetworkInterface,您可以使用GetIPProperties method获取IPInterfaceProperties对象,并且可以从IPInterfaceProperties对象访问UnicastAddresses property以获取UnicastIPAddressInformation对象的列表 .

    • 通过检查 DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred 过滤掉非首选单播地址

    • 通过检查 AddressPreferredLifetime != UInt32.MaxValue 过滤掉"virtual"地址 .

    此时,我获取与所有这些过滤器匹配的第一个(如果有)单播地址的地址 .

    编辑:

    [修订后的代码于2018年5月16日,包括上述文本中提到的重复地址检测状态和首选寿命]

    下面的示例演示了基于操作状态,地址族的过滤,不包括环回地址(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);
    }
    
  • 9
    WebClient webClient = new WebClient();
    string IP = webClient.DownloadString("http://myip.ozymo.com/");
    
  • 3
    using System.Net;
    
    string host = Dns.GetHostName();
    IPHostEntry ip = Dns.GetHostEntry(host);
    Console.WriteLine(ip.AddressList[0].ToString());
    

    刚刚在我的机器上测试了它,它的工作原理 .

  • 50

    如果您想避免使用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);
            }
        }
    }
    
  • 8

    不要一直依赖InterNetwork,因为你可以拥有多个同时使用IP4的设备,这会破坏获取IP的结果 . 现在,如果您愿意,可以复制一下,请查看或更新为您认为合适的方式 .

    首先,我得到路由器的地址(网关)如果它返回我连接到网关(这意味着没有直接连接到调制解调器无线),那么我们的网关地址为IPAddress,否则我们是空指针IPAddress参考 .

    然后我们需要获取计算机的IP地址列表 . 事情并不困难,因为路由器(所有路由器)使用4个字节(...) . 前三个是最重要的,因为连接到它的任何计算机将具有与前三个字节匹配的IP4地址 . 例如:192.168.0.1是路由器默认IP的标准,除非由管理员更改 . '192.168.0'或者它们可能是我们需要匹配的东西 . 这就是我在IsAddressOfGateway函数中所做的一切 . 长度匹配的原因是因为并非所有地址(仅用于计算机)都具有4个字节的长度 . 如果在cmd中键入netstat,您会发现这是真的 . 所以你有它 . 是的,真正得到你想要的东西需要更多的工作 . 排除法 . 并且为了上帝的缘故,不要通过ping它来找到地址,这需要时间,因为首先你要发送要被ping的地址然后它必须发回结果 . 不,直接使用.Net类来处理您的系统环境,当您必须单独使用计算机时,您将获得所需的答案 .

    现在,如果你直接连接到你的调制解调器,过程几乎是相同的,因为调制解调器是你的网关,但子掩码不一样,因为你通过调制解调器直接从你的DNS服务器获取信息,而不是由提供调制解调器的路由器屏蔽互联网给你,虽然你仍然可以使用相同的代码,因为分配给调制解调器的IP的最后一个字节是1.因此,如果从发生变化的调制解调器发送的IP是111.111.111.1'那么你将获得111.111.111 . (一些字节值) . 请记住,我们需要找到网关信息,因为有更多的设备处理互联网连接而不是路由器和调制解调器 .

    现在你明白为什么你不要改变你的路由器前两个字节192和168.这些只是严格区分路由器而不是互联网使用,否则我们会遇到严重的IP协议和双重ping问题导致计算机崩溃 . 您分配的路由器IP为192.168.44.103的图像,并且您也单击具有该IP的站点 . 我的天啊!您的计算机不知道要ping什么 . 崩溃就在那里 . 为避免此问题,仅为路由器分配这些,而不是用于Internet使用 . 所以留下路由器的前两个字节 .

    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;
    }
    
  • 81

    我只是想我会添加自己的,单行(即使已经有许多其他有用的答案) .


    string ipAddress = new WebClient().DownloadString("http://icanhazip.com");

  • 15

    要获取当前的公共IP地址,您需要做的就是在页面加载事件上创建一个带有以下行的ASPX页面:

    Response.Write(HttpContext.Current.Request.UserHostAddress.ToString());
    
  • 1

    如果您在Intranet中运行,您将能够获得本地计算机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());
    
  • 0
    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;
                }
            }
        }
    }
    

    请查看here了解详情 .

    你必须记住你的计算机可以有多个IP(实际上它总是这样) - 所以你要去哪一个 .

  • 234

    试试这个:

    IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
     String MyIp = localIPs[0].ToString();
    
  • 1

    也许通过 external IP你可以考虑(如果你在Web服务器上下文中)使用它

    Request.ServerVariables["LOCAL_ADDR"];
    

    我问的是和你一样的问题,我在this stackoverflow文章中找到了它 .

    它对我有用 .

  • 0
    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;
            }    
         }
    }
    
  • 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();
            }
        }
    }
    
  • 1
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
    

    返回第一个内部IPV4地址的简单单行代码,如果没有则返回null . 作为上面的评论添加,但可能对某人有用(上面的一些解决方案将返回需要进一步过滤的多个地址) .

    它也很容易返回loopback而不是null我猜:

    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );
    
  • 1

    为了找到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();
    }
    
  • 162

    LINQ解决方案:

    Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).FirstOrDefault() ?? ""
    
  • 1

    这是我如何解决它 . 我知道如果你有几个物理接口,这可能不会选择你想要的确切的eth .

    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;
    }
    
  • 37

    问题并不是说ASP.NET MVC,但我还是把它留在这里:

    Request.UserHostAddress
    
  • 4

    使用LINQ将所有IP地址作为字符串获取:

    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();
    

    TO FILTER OUT PRIVATE ONES...

    首先,定义一个扩展方法 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();
    
  • 4

    它适用于我...并且在大多数情况下(如果不是全部)应该比查询DNS服务器更快 . 感谢Wily博士的学徒(here) .

    // ************************************************************************
    /// <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://stackoverflow.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://stackoverflow.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;
            }
    
            // ******************************************************************
    
        }
    }
    
  • 1

    以最快的方式获取远程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秒),但之后它将始终在0-2秒内获取您的远程IP地址,具体取决于您的连接 .

    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;
    }
    

相关问题