如何在C#中获取用户的公共IP地址

54

我想要知道使用我的网站的客户端的公共IP地址。 下面的代码显示的是在局域网中的本地IP,但我想要客户端的公共IP。

//get mac address
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sMacAddress = string.Empty;
foreach (NetworkInterface adapter in nics)
{
    if (sMacAddress == String.Empty)// only return MAC Address from first card  
    {
        IPInterfaceProperties properties = adapter.GetIPProperties();
        sMacAddress = adapter.GetPhysicalAddress().ToString();
    }
}
// To Get IP Address


string IPHost = Dns.GetHostName();
string IP = Dns.GetHostByName(IPHost).AddressList[0].ToString();

输出:

IP地址:192.168.1.7

请帮我获取公共IP地址。


@Parker 虽然他的代码看起来像是重复的,但实际上他是在询问关于 ASP.NET 和获取客户端地址的问题,这是非常可行的。 - Scott Chamberlain
你好,有没有什么原因导致您在一年半之后取消了我的答案?如果您是故意这样做的,那么能否请您给出评论?谢谢。 - FeliceM
16个回答

72

这是我使用的内容:

protected void GetUser_IP()
{
    string VisitorsIPAddr = string.Empty;
    if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
    {
        VisitorsIPAddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
    }
    else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
    {
        VisitorsIPAddr = HttpContext.Current.Request.UserHostAddress;
    }
    uip.Text = "Your IP is: " + VisitorsIPAddr;
}

"uip"是aspx页面中显示用户IP的标签名称。


对象引用未设置为对象的实例。 if (HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) - Neeraj Mehta
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(""); direction = direction.Substring(first, last - first); return direction;这个代码可以帮助我获取IP地址,但是如果访问的网站宕机了怎么办? - Neeraj Mehta
你是什么意思?你测试了我在答案中给出的代码吗?它在我所有的网站上都能正常工作。告诉我你把代码放在哪里了。那可能是问题所在。 - FeliceM
5
如果这个方法返回IP地址而不是输出到一个asp.net标签控件会更好。 - hanzolo
对我来说,它返回托管我的网站的机器的IP。与以下代码完全相同: string ip = Request.ServerVariables["REMOTE_ADDR"]; - Иво Недев

24

您可以使用 "HTTP_X_FORWARDED_FOR" 或 "REMOTE_ADDR" 标头属性。

请参考来自Machine Syntax博客的GetVisitorIPAddress方法。

    /// <summary>
    /// method to get Client ip address
    /// </summary>
    /// <param name="GetLan"> set to true if want to get local(LAN) Connected ip address</param>
    /// <returns></returns>
    public static string GetVisitorIPAddress(bool GetLan = false)
    {
        string visitorIPAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (String.IsNullOrEmpty(visitorIPAddress))
            visitorIPAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

        if (string.IsNullOrEmpty(visitorIPAddress))
            visitorIPAddress = HttpContext.Current.Request.UserHostAddress;

        if (string.IsNullOrEmpty(visitorIPAddress) || visitorIPAddress.Trim() == "::1")
        {
            GetLan = true;
            visitorIPAddress = string.Empty;
        }

        if (GetLan && string.IsNullOrEmpty(visitorIPAddress))
        {
                //This is for Local(LAN) Connected ID Address
                string stringHostName = Dns.GetHostName();
                //Get Ip Host Entry
                IPHostEntry ipHostEntries = Dns.GetHostEntry(stringHostName);
                //Get Ip Address From The Ip Host Entry Address List
                IPAddress[] arrIpAddress = ipHostEntries.AddressList;

                try
                {
                    visitorIPAddress = arrIpAddress[arrIpAddress.Length - 2].ToString();
                }
                catch
                {
                    try
                    {
                        visitorIPAddress = arrIpAddress[0].ToString();
                    }
                    catch
                    {
                        try
                        {
                            arrIpAddress = Dns.GetHostAddresses(stringHostName);
                            visitorIPAddress = arrIpAddress[0].ToString();
                        }
                        catch
                        {
                            visitorIPAddress = "127.0.0.1";
                        }
                    }
                }

        }


        return visitorIPAddress;
    }

我已经在Azure VM上尝试过了,arrIpAddress[0]包含IPv6地址,这是正确的String,因此Catch没有被执行,在结果中我们得到了IPv6而不是本地IPv4或127.0.0.1。IPv4保留在arrIpAddress[1]中。在这种情况下,我应该如何处理才能获得IPv4呢? - Megrez7

12

结合这些建议及其背后的原因。也可以自由添加更多测试用例。如果获取客户端IP非常重要,那么您可能需要获取所有这些并对哪个结果更准确进行一些比较。

对本主题中所有建议的简单检查以及我自己的一些代码...

    using System.IO;
    using System.Net;

    public string GetUserIP()
    {
        string strIP = String.Empty;
        HttpRequest httpReq = HttpContext.Current.Request;

        //test for non-standard proxy server designations of client's IP
        if (httpReq.ServerVariables["HTTP_CLIENT_IP"] != null)
        {
            strIP = httpReq.ServerVariables["HTTP_CLIENT_IP"].ToString();
        }
        else if (httpReq.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
        {
            strIP = httpReq.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
        }
        //test for host address reported by the server
        else if
        (
            //if exists
            (httpReq.UserHostAddress.Length != 0)
            &&
            //and if not localhost IPV6 or localhost name
            ((httpReq.UserHostAddress != "::1") || (httpReq.UserHostAddress != "localhost"))
        )
        {
            strIP = httpReq.UserHostAddress;
        }
        //finally, if all else fails, get the IP from a web scrape of another server
        else
        {
            WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
            using (WebResponse response = request.GetResponse())
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                strIP = sr.ReadToEnd();
            }
            //scrape ip from the html
            int i1 = strIP.IndexOf("Address: ") + 9;
            int i2 = strIP.LastIndexOf("</body>");
            strIP = strIP.Substring(i1, i2 - i1);
        }
        return strIP;
    }

10

9

针对 Web 应用(ASP.NET MVC 和 WebForm)

/// <summary>
/// Get current user ip address.
/// </summary>
/// <returns>The IP Address</returns>
public static string GetUserIPAddress()
{
    var context = System.Web.HttpContext.Current;
    string ip = String.Empty;

    if (context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
        ip = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
    else if (!String.IsNullOrWhiteSpace(context.Request.UserHostAddress))
        ip = context.Request.UserHostAddress;

    if (ip == "::1")
        ip = "127.0.0.1";

    return ip;
}

针对Windows应用程序(Windows表单,控制台,Windows服务等)

    static void Main(string[] args)
    {
        HTTPGet req = new HTTPGet();
        req.Request("http://checkip.dyndns.org");
        string[] a = req.ResponseBody.Split(':');
        string a2 = a[1].Substring(1);
        string[] a3=a2.Split('<');
        string a4 = a3[0];
        Console.WriteLine(a4);
        Console.ReadLine();
    }

6

有很多代码片段都很大,可能会让寻求帮助的新程序员感到困惑。

那么这个简单而紧凑的代码如何获取访问者的IP地址呢?

string ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (string.IsNullOrEmpty(ip))
        {
            ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        }

简单、简短、紧凑。

4

我有一个扩展方法:

public static string GetIp(this HttpContextBase context)
{
    if (context == null || context.Request == null)
        return string.Empty;

    return context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 
           ?? context.Request.UserHostAddress;
}

注意:"HTTP_X_FORWARDED_FOR" 用于代理后的IP。context.Request.UserHostAddress 与 "REMOTE_ADDR" 相同。
但请记住,它不一定是实际的IP。
来源: IIS服务器变量 链接

4

我的版本可以处理ASP.NET或局域网IP:

/** 
 * Get visitor's ip address.
 */
public static string GetVisitorIp() {
    string ip = null;
    if (HttpContext.Current != null) { // ASP.NET
        ip = string.IsNullOrEmpty(HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"])
            ? HttpContext.Current.Request.UserHostAddress
            : HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    }
    if (string.IsNullOrEmpty(ip) || ip.Trim() == "::1") { // still can't decide or is LAN
        var lan = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(r => r.AddressFamily == AddressFamily.InterNetwork);
        ip = lan == null ? string.Empty : lan.ToString();
    }
    return ip;
}

2
 private string GetClientIpaddress()
    {
        string ipAddress = string.Empty;
        ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (ipAddress == "" || ipAddress == null)
        {
            ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            return ipAddress;
        }
        else
        {
            return ipAddress;
        }
    }

2
在MVC 5中,您可以使用以下代码:
string cIpAddress = Request.UserHostAddress; //Gets the client ip address

或者

string cIpAddress = Request.ServerVariables["REMOTE_ADDR"]; //Gets the client ip address

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接