Search code examples
javaphpandroidsocketsnat

How do I access a ServerSocket behind an NAT router?


Goal

I'm making a chat application for android and am currently testing with 2 phones which must eventually work for a few thousand users.

Problem

I get a ConnectionException saying "Connection refused" whenever the 2 phones try connecting to each other via sockets.

Current Design

Each phone starts a ServerSocket, calls the accept() method waiting for some Socket to connect to, and whichever phone sends a message first will create a client Socket. I'm certain the IP addresses I'm using are correct (they're actually both using the same external IP). I believe the problem is with the ports. I generate a port number at random, and if it's free to use, I say ServerSocket s = new ServerSocket( randomPortNumber ).

What I think is the source of the problem

What I think is the problem is this port number is one sitting behind an NAT router. So when a Socket tries to connect to the ServerSocket using something like Socket socket = new Socket( ip, serverSocketRandomPortNumber ), it will try to connect to the NAT router and feed it this port number which won't work since the router itself is not listening on this port, but the phone behind the router is.

Questions and thoughts

My question is, how do I deal with this problem?

Do I have to change my design?

If I must, an alternative design I'm thinking of is using a single ServerSocket on a web host and use it to redirect messages sent from client sockets to other client sockets.

I'd be implementing the server-side in php referencing something along these lines: http://php.net/manual/en/sockets.examples.php

And I would still use Java for the client-side.


Solution

  • Since one of the phones is behind a NAT router, nothing can initiate a connection to it unless port forwarding (or some other techniques) is enabled on the router.

    The usual way a chat application is implemented is, there is a common server that all clients will connect to.

    You don't have to write your own chat server (unless you really want to). I suggest using the XMPP protocol. A list of already made servers here. On the client side (Android), you can find libraries you can use here.