views:

7850

answers:

5

you know we have Request.UserHostAddress to get ip address in asp.net ,but this is usually user's ISP ip address not exactly user's machine ip who for example clicked a link.
how can i get real IP Address?

for example in stackoverflow user profile it is: "Last account activity: 4 hours ago from 86.123.127.8" but my machine ip address is a bit different.
how stackoverflow gets this address?
in some web systems there is a ip check for some purposes for example: with a certian ip in every 24 hours just the user can have only 5 clicks on download links? this ip address should be unique. not for an ISP that has a huge range of clients or internet users.
did i unrdestand well?

+10  A: 

What else do you consider the user IP address? If you want the IP address of the network adapter, I'm afraid there's no possible way to do it in a Web app. If your user is behind NAT or other stuff, you can't get the IP either.

Update: While there are Web sites that use IP to limit the user (like rapidshare), they don't work correctly in NAT environments.

Mehrdad Afshari
+2  A: 

IP addresses are part of the Network layer in the "seven-layer stack". The Network layer can do whatever it wants to do with the IP address. That's what happens with a proxy server, NAT, relay, or whatever.

The Application layer should not depend on the IP address in any way. In particular, an IP Address is not meant to be an identifier of anything other than the idenfitier of one end of a network connection. As soon as a connection is closed, you should expect the IP address (of the same user) to change.

John Saunders
+11  A: 

As others have said you can't do what you are asking. If you describe the problem you are trying to solve maybe someone can help? E.g. are you trying to uniquely identify your users? Could you use a cookie, or the session ID perhaps instead of the IP address?

Edit The address you see on the server shouldn't be the ISP's address, as you say that would be a huge range. The address for a home user on broadband will be the address at their router, so every device inside the house will appear on the outside to be the same, but the router uses NAT to ensure that traffic is routed to each device correctly. For users accessing from an office environment the address may well be the same for all users. Sites that use IP address for ID run the risk of getting it very wrong - the examples you give are good ones and they often fail. For example my office is in the UK, the breakout point (where I "appear" to be on the internet) is in another country where our main IT facility is, so from my office my IP address appears to be not in the UK. For this reason I can't access UK only web content, such as the BBC iPlayer (and my employer is probably very happy about this:-) ). AT any given time there would be hundreds, or even thousands of people at my company who appear to be accessing the web from the same IP address.

When you are writing server code you can never be sure what the IP address you see is refering to.In fact some users like it this way. Some people deliberately use an annoymising proxy to further confound you, for security or privacy reasons they route their web traffic via a proxy so that you won't know who or where that user is.

When you say your machine address is different to the IP address shown on StackOverflow, how are you finding out your machine address? If you are just looking locally using ipconfig or something like that I would expect it to be different for the reasons I outlined above. If you want to double check what the outside world thinks have a look at whatismyipaddress.com/.

This Wikipedia link on NAT will provide you some background on this.

Steve Haigh
so I understood in server side applications we cant be sure about IP address. it means that client side programming is the solution?? you mean for example with some JavaScript codes we can do that??
mahdiahmadirad
NO, this would be pointless, the IP address the client "thinks" it has will be internal to the home or office, it will be meaningless in the outside world. E.g. most home routers hand out IP addresses in the range 192.168.1.xxx, so thousands of machines have the same address on their own networks.
Steve Haigh
thank you very much for your informations.
mahdiahmadirad
You're very welcome:-)
Steve Haigh
but this is a new Question: if the result of Request.UserHostAddress is unique for each user or not?my purpose is to catch how many times a user clicks on a link by IP address,Request.UserHostAddress can do that?here is not important IP is correct or not challenge is to reach unique ip for each user
mahdiahmadirad
No, it is not unique. Two users behind the same router using NAT will have the same IP address. I really think you need to read up on this, see link in my edit.
Steve Haigh
+5  A: 

Often you will want to know the IP Address of someone visiting your website. While Asp.Net has several ways to do this one of the best we've seen is by using the "HTTP_X_FORWARDED_FOR" of the Server Variables collection.

Here's why...

Sometimes your visitors are behind either a proxy server or a router and the standard Request.UserHostAddress() only captures the IP of the proxy server or router. When this is the case the users IP is then stored in the Server Variable ("HTTP_X_FORWARDED_FOR")

So what we want to do is first check the "HTTP_X_FORWARDED_FOR" and if that is empty we then simply return the ServerVariables("REMOTE_ADDR").

While this method is not foolproof, it can lead to better results. Below is the Asp.Net code in VB, taken from James Crowley's blog.

'http://weblogs.asp.net/james_crowley/
     archive/2007/06/19/
     gotcha-http-x-forwarded-for-returns-multiple-ip-addresses.aspx

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
mangokun