Hey guys,

Here's the problem I have:

I am writing a server application in Java using the ServerSocket and Socket classes. I have an instance of ServerSocket which listens for connection and accepts them. The server runs a website that requires users to log in using an e-mail and a password. Everything works fine until I tried it on my local network at home - I am using a wireless router for 3 computers and they all share the same IP address and differ by their local address, e.g. one is 192.168.1.1 and another is 192.168.1.2, etc. The problem is that whenever I call

...
Socket s = null;
while ( true ) {
    s = socket.accept();
    System.out.println( "ADDRESS: " + s.getLocalAddress().getHostAddress() );
    ...
}

it prints my current local address (192.168.1.2) even when I enter the website from one of the other computers, which means that I can log in from one pc and I would automatically logged in the others as well, since I am using the local address as a unique identifier for each connection.

My question is: is that the correct way to get the local IP and why is it printing the same address even when I am loading the site from a different computer?

Thanks. (pls let me know if you need to know anything else)

getLocalAddress "Gets the local address to which the socket is bound" (API doc). This is address of the machine where the server is running, so of course its always the same, regardless of where the client is.
getRemoteSocketAddress() will give you the address where the client is, if that's what you need.

Thanks for the reply :) I've tried this but it gives me the IP address of the machine, which is the same on all three here at home. I just changed this:

System.out.println( "ADDRESS: " + s.getLocalAddress().getHostAddress() );

to:

System.out.println( "ADDRESS: " + s.getRemoteSocketAddress() );

AFAIK, this is expected. The IP address assigned to you by your ISP is the external IP address whereas the unique IP addresses of each of your network machines are "internal" addresses which aren't viewable to the outside world. This is one of the reasons why browsers don't just rely on IP addresses for client identification but use a token mechanism like passing token (session id) using cookies or by appending it to the URL (another one is client using proxy servers).

So to answer your query, this isn't just about "different" computers but about public IP addresses. A solution around this would be to use a token mechanism i.e. generating hashes and assigning them to clients which connect to your server and "destroy" or "invalidate" the hash when the client logs off or a certain period of inactivity is observed.

Comments
thanks for the suggestion :)

Let me check: you server is still somewhere on the net but your client is on a LAN behind a NAT router? In which case the server just sees the routers's internet address as the getRemoteSocketAddress() for all such clients?
In that case, can't you use the ip address plus port number to distinguish between these clients? (The router should map them all to different outgoing port numbers.)

ps: Even so, ~s.o.s~ has pointed you in a better direction

Edited 5 Years Ago by JamesCherrill: ps

Comments
that could work as well :)

The router does the routing of incoming messages to anything residing behind it.
Unless each client is accessing your server through a different TCP or UDP port there's no way for the server to distinguish them unless you send specific information in each request/response to the client and the client then returns that information (which is how session management in http works, roughly).

Doesn't a standard NAT router map each LAN IP/port to a different arbitrary port on the WAN IP - so each unique LAN client will appear as a different port number on the external IP? I'm no expert on this, so I'd be grateful for a correction if I have this wrong. Thanks.

Edited 5 Years Ago by JamesCherrill: n/a

This question has already been answered. Start a new discussion instead.