Android app accepts local but not remote TCP connection

android, java, network-programming, sockets, tcp

Solution

Most wireless services assign only non-routable RFC1918 addresses to devices, and route "the internet" through NAT. That means your device can make outbound connections - but you cannot connect to it from the outside (inbound). One reason is the lack of free IPv4 address space.

Since your post mentions Port 21: If you want FTP, use passive mode. In this mode the Android device will make the data connection to the server.

Problem

Very stuck on this one, so I appreciate any help you can give! I have two programs, an Android app and a multi-socket Java server. The Android app first establishes an outbound connection to the server (port 21) then accepts in inbound connection from the server (port 1025). For consistency I'll always call the Android app the client and the Java app the host, regardless of the direction the connection is being established in. The programs work perfectly on a local network, with either my android phone connecting to my local server ip `192.168.1.103` or the emulator on the PC hosting the server connecting to `10.0.2.2`. However when I move outside of my local intranet, I can still establish the android->server connection on port 21 but I time out trying to connect from the server to the phone on port 1025. A list of things I am accounting for: - Android emulator has port 1025 redirected - Windows (Win 7 server host) firewall is disabled, other known firewalls are disabled - The incoming connection listener is not on the main thread (SDK 2.1 so shouldn't matter) - Router ports 21 and 1025 are being forwarded A list of tests and their outcomes: - Connecting to server's public ip (router present) from emulator/android phone on local network/android phone on remote network - fails to establish server->phone connection - Removing router and connecting from emulator or remote android phone - fails to establish server->phone connection - Connecting from emulator to `10.0.2.2`, router present or not - succeeds - Connecting from android phone on local network to `192.168.1.103` - succeeds And finally some code, the Servers's output connection attempt (connection is created in the constructor since a sub-thread for this client was already created upon the server's receipt of an inbound connection) ``` OutputSocketServer(InetAddress inetAddress, int port, int count , LinkedBlockingQueue<Packet> outQueue) { this.outQueue = outQueue; SocketAddress sockaddr = new InetSocketAddress(inetAddress,port); try { outConnection = new Socket(); System.out.println("Connecting to " + sockaddr.toString()); outConnection.connect(sockaddr, timeout); System.out.println("Connected to port " + outConnection.getPort() + " of " +outConnection.getInetAddress().toString() + " from local port " + outConnection.getLocalPort()); osw = new ObjectOutputStream(outConnection.getOutputStream()); } catch (IOException e) { System.out.println("Output Socket Server: Could not establish outbound connection" + e.toString()); e.printStackTrace(); } } ``` and the relevant part of the Android Client's connection accept code ``` public void run() { try { System.out.println("Listening for connection on local port " + inSocket.getLocalPort()); this.inConnection = inSocket.accept(); System.out.println("Accepted connection on port " + inConnection.getPort() + " from ip " + inConnection.getInetAddress().toString()); isr = new ObjectInputStream(inConnection.getInputStream()); } catch (Exception e) { System.out.println("Inbound Socket Server: " + e.toString()); } } ``` The stack trace for the android client just says `SocketTimeoutException: operation timed out` and for the server `ConnectException: connection refused: connect`. Prior to that the client's LogCat shows `Listening for connection on port 1025` and the server `Connecting to /my.ip.he.re:1025` Thanks for any guidance!

Original source