как получить локальный IP-адрес клиента, который использует мой доменный URL? [Дубликат]

Если мы рассмотрим общие сценарии, в которых может быть выбрано это исключение, доступ к свойствам с объектом вверху.

Пример:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

здесь, если адрес имеет значение null, то вы получите NullReferenceException.

Итак, в качестве практики мы всегда должны использовать проверку нуля, прежде чем обращаться к свойствам в таких объектах (особенно в общих)

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception
332
задан Peter Mortensen 1 May 2011 в 10:52
поделиться

16 ответов

Как говорили другие, вы не можете делать то, что вы просите. Если вы описываете проблему, которую пытаетесь решить, может быть, кто-то может помочь? Например. вы пытаетесь однозначно идентифицировать своих пользователей? Можете ли вы использовать cookie или идентификатор сеанса, возможно, вместо IP-адреса?

Изменить Адрес, который вы видите на сервере, не должен быть адресом интернет-провайдера, как вы говорите, это будет огромный диапазон. Адрес для домашнего пользователя в широкополосной сети будет адресом на своем маршрутизаторе, поэтому все устройства внутри дома будут отображаться снаружи одинаковыми, но маршрутизатор использует NAT, чтобы гарантировать, что трафик перенаправляется на каждое устройство правильно. Для пользователей, получающих доступ из офисной среды, адрес может быть одинаковым для всех пользователей. Сайты, использующие IP-адрес для идентификатора, рискуют сделать его очень неправильным - примеры, которые вы даете, хороши, и они часто терпят неудачу. Например, мой офис находится в Великобритании, точка прорыва (где я «появляюсь» в Интернете) находится в другой стране, где находится наш главный ИТ-центр, поэтому из моего офиса мой IP-адрес, похоже, не в Великобритании. По этой причине я не могу получить доступ к только веб-контенту в Великобритании, например, iPlayer BBC). В любой момент времени в моей компании будут сотни или даже тысячи людей, которые, как представляется, обращаются к веб-сайту с одного и того же IP-адреса.

Когда вы пишете код сервера, вы никогда не можете быть уверены, что указывает IP-адрес, на который вы ссылаетесь. Некоторым пользователям это нравится. Некоторые люди намеренно используют прокси-сервер или VPN, чтобы еще больше смутить вас.

Когда вы говорите, что ваш машинный адрес отличается от IP-адреса, указанного в StackOverflow, как вы узнаете свой машинный адрес? Если вы просто смотрите локально с помощью ipconfig или чего-то подобного, я бы ожидал, что он будет отличаться по причинам, изложенным выше. Если вы хотите дважды проверить, что внешний мир думает, посмотрите whatismyipaddress.com / .

Эта ссылка Wikipedia на NAT предоставит вам некоторые фон на этом.

128
ответ дан Steve Haigh 3 September 2018 в 13:04
поделиться

Если это c #, см. этот способ, очень просто

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? 
                   Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
20
ответ дан 2Toad 3 September 2018 в 13:04
поделиться

Часто вам нужно знать IP-адрес того, кто посещает ваш сайт. В то время как ASP.NET имеет несколько способов сделать это, одним из лучших способов, которые мы видели, является использование «HTTP_X_FORWARDED_FOR» коллекции ServerVariables.

Вот почему ...

Иногда ваши посетители находятся за прокси-сервером или маршрутизатором, а стандарт Request.UserHostAddress фиксирует только IP-адрес прокси-сервера или маршрутизатора. Если это так, тогда IP-адрес пользователя сохраняется в переменной сервера («HTTP_X_FORWARDED_FOR»).

Итак, мы хотим сначала проверить «HTTP_X_FORWARDED_FOR», и если это пусто, мы просто возвращаем ServerVariables("REMOTE_ADDR").

Хотя этот метод не является надежным, он может привести к лучшим результатам. Ниже представлен код ASP.NET в VB.NET, взятый из сообщения g0 Джеймс Кроули «Gotcha: HTTP_X_FORWARDED_FOR возвращает несколько IP-адресов»

C #

protected string GetIPAddress()
{
    System.Web.HttpContext context = System.Web.HttpContext.Current; 
    string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

    if (!string.IsNullOrEmpty(ipAddress))
    {
        string[] addresses = ipAddress.Split(',');
        if (addresses.Length != 0)
        {
            return addresses[0];
        }
    }

    return context.Request.ServerVariables["REMOTE_ADDR"];
}

VB.NET

Public Shared Function GetIPAddress() As String
    Dim context As System.Web.HttpContext = System.Web.HttpContext.Current
    Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    If String.IsNullOrEmpty(sIPAddress) Then
        Return context.Request.ServerVariables("REMOTE_ADDR")
    Else
        Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})
        Return ipArray(0)
    End If
End Function
385
ответ дан AFract 3 September 2018 в 13:04
поделиться

ОБНОВЛЕНИЕ: Спасибо Бруно Лопесу. Если вам понадобится несколько IP-адресов, необходимо использовать этот метод:

    private string GetUserIP()
    {
        string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (!string.IsNullOrEmpty(ipList))
        {
            return ipList.Split(',')[0];
        }

        return Request.ServerVariables["REMOTE_ADDR"];
    }
68
ответ дан algreat 3 September 2018 в 13:04
поделиться

используйте этот параметр

Dns.GetHostEntry(Dns.GetHostName())
-3
ответ дан Andrew Barber 3 September 2018 в 13:04
поделиться

Вы можете использовать:

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();
15
ответ дан Bat_Programmer 3 September 2018 в 13:04
поделиться

использовать в файле ashx

public string getIP(HttpContext c)
{
    string ips = c.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (!string.IsNullOrEmpty(ips))
    {
        return ips.Split(',')[0];
    }
    return c.Request.ServerVariables["REMOTE_ADDR"];
}
3
ответ дан Behnam Mohammadi 3 September 2018 в 13:04
поделиться

Все ответы до сих пор учитывают нестандартизированный, но очень общий заголовок X-Forwarded-For. Существует стандартизованный заголовок Forwarded , который немного сложнее разобрать. Вот несколько примеров:

Forwarded: for="_gazonk"
Forwarded: For="[2001:db8:cafe::17]:4711"
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17

Я написал класс, который учитывает оба этих заголовка при определении IP-адреса клиента.

using System;
using System.Web;

namespace Util
{
    public static class IP
    {
        public static string GetIPAddress()
        {
            return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));
        }

        internal static string GetIPAddress(HttpRequestBase request)
        {
            // handle standardized 'Forwarded' header
            string forwarded = request.Headers["Forwarded"];
            if (!String.IsNullOrEmpty(forwarded))
            {
                foreach (string segment in forwarded.Split(',')[0].Split(';'))
                {
                    string[] pair = segment.Trim().Split('=');
                    if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))
                    {
                        string ip = pair[1].Trim('"');

                        // IPv6 addresses are always enclosed in square brackets
                        int left = ip.IndexOf('['), right = ip.IndexOf(']');
                        if (left == 0 && right > 0)
                        {
                            return ip.Substring(1, right - 1);
                        }

                        // strip port of IPv4 addresses
                        int colon = ip.IndexOf(':');
                        if (colon != -1)
                        {
                            return ip.Substring(0, colon);
                        }

                        // this will return IPv4, "unknown", and obfuscated addresses
                        return ip;
                    }
                }
            }

            // handle non-standardized 'X-Forwarded-For' header
            string xForwardedFor = request.Headers["X-Forwarded-For"];
            if (!String.IsNullOrEmpty(xForwardedFor))
            {
                return xForwardedFor.Split(',')[0];
            }

            return request.UserHostAddress;
        }
    }
}

Ниже приведены некоторые единицы тесты, которые я использовал для проверки моего решения:

using System.Collections.Specialized;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UtilTests
{
    [TestClass]
    public class IPTests
    {
        [TestMethod]
        public void TestForwardedObfuscated()
        {
            var request = new HttpRequestMock("for=\"_gazonk\"");
            Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv6()
        {
            var request = new HttpRequestMock("For=\"[2001:db8:cafe::17]:4711\"");
            Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4()
        {
            var request = new HttpRequestMock("for=192.0.2.60;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4WithPort()
        {
            var request = new HttpRequestMock("for=192.0.2.60:443;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedMultiple()
        {
            var request = new HttpRequestMock("for=192.0.2.43, for=198.51.100.17");
            Assert.AreEqual("192.0.2.43", Util.IP.GetIPAddress(request));
        }
    }

    public class HttpRequestMock : HttpRequestBase
    {
        private NameValueCollection headers = new NameValueCollection();

        public HttpRequestMock(string forwarded)
        {
            headers["Forwarded"] = forwarded;
        }

        public override NameValueCollection Headers
        {
            get { return this.headers; }
        }
    }
}
6
ответ дан dana 3 September 2018 в 13:04
поделиться

Попробуйте:

using System.Net;

public static string GetIpAddress()  // Get IP Address
{
    string ip = "";     
    IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());
    IPAddress[] addr = ipEntry.AddressList;
    ip = addr[2].ToString();
    return ip;
}
public static string GetCompCode()  // Get Computer Name
{   
    string strHostName = "";
    strHostName = Dns.GetHostName();
    return strHostName;
}
-7
ответ дан EM-Creations 3 September 2018 в 13:04
поделиться
string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
8
ответ дан GorkemHalulu 3 September 2018 в 13:04
поделиться

IP-адреса являются частью сетевого уровня в «семислойном стеке». Сетевой уровень может делать все, что он хочет сделать с IP-адресом. Это то, что происходит с прокси-сервером, NAT, реле и т. Д.

Уровень приложения не должен зависеть от IP-адреса. В частности, IP-адрес не должен быть идентификатором чего-либо иного, кроме idenfitier одного конца сетевого соединения. Как только соединение будет закрыто, вы должны ожидать, что IP-адрес (того же пользователя) изменится.

14
ответ дан John Saunders 3 September 2018 в 13:04
поделиться

Думаю, я должен поделиться своим опытом со всеми вами. Я вижу, что в некоторых ситуациях REMOTE_ADDR НЕ доставит вам то, что вы ищете. Например, если у вас есть балансировщик нагрузки за сценой, и если вы пытаетесь получить IP-адрес клиента, у вас будут проблемы. Я проверил его с помощью своего программного обеспечения для маскировки IP-адресов, а также проверил, что мои коллеги находятся на разных континентах. Итак, вот мое решение.

Когда я хочу узнать IP-адрес клиента, я пытаюсь выбрать все возможные доказательства, чтобы определить, уникальны ли они:

Здесь я нашел другой sever-var, который может помочь вам всем, если вы хотите получить точный IP-адрес на стороне клиента. поэтому я использую: HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IP всегда получает точный IP-адрес клиента. В любом случае, если он не дает вам значение, вы должны искать HTTP_X_FORWARDED_FOR, поскольку он является вторым лучшим кандидатом для получения вашего IP-адреса клиента, а затем REMOTE_ADDR var, который может или не может вернуть вам IP-адрес, но для меня есть все эти три - это то, что я нахожу лучше всего для их наблюдения.

Надеюсь, это поможет некоторым парням.

21
ответ дан KMX 3 September 2018 в 13:04
поделиться

Что еще вы считаете IP-адресом пользователя? Если вам нужен IP-адрес сетевого адаптера, я боюсь, что нет возможности сделать это в веб-приложении. Если ваш пользователь находится за NAT или другими вещами, вы также не можете получить IP.

Обновление. Хотя существуют веб-сайты, которые используют IP для ограничения пользователя (например, rapidshare), они не работают правильно в средах NAT.

23
ответ дан Mehrdad Afshari 3 September 2018 в 13:04
поделиться

Что вы можете сделать, это сохранить IP-адрес маршрутизатора вашего пользователя, а также перенаправленный IP-адрес и попытаться сделать его надежным, используя оба IP-адреса [External Public и Internal Private]. Но через несколько дней клиенту может быть назначен новый внутренний IP-адрес от маршрутизатора, но он будет более надежным.

7
ответ дан Shahid 3 September 2018 в 13:04
поделиться

Объединив ответы из @Tony и @mangokun , я создал следующий метод расширения:

public static class RequestExtensions
{
    public static string GetIPAddress(this HttpRequest Request)
    {
        if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();

        if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
        {
            string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

            if (!string.IsNullOrEmpty(ipAddress))
            {
                string[] addresses = ipAddress.Split(',');
                if (addresses.Length != 0)
                {
                    return addresses[0];
                }
            }
        }

        return Request.UserHostAddress;
    }
}
3
ответ дан sikander 3 September 2018 в 13:04
поделиться

Если вы используете CloudFlare, вы можете попробовать этот метод расширения :

public static class IPhelper
{
    public static string GetIPAddress(this HttpRequest Request)
    {
        if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();

        if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();

        return Request.UserHostAddress;
    }
}

, затем

string IPAddress = Request.GetIPAddress();
9
ответ дан Tony 3 September 2018 в 13:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: