Ted Jackson
Ted Jackson

Reputation: 1

ServerSocket tcp server on pc unreachable by Android phone client

hope someone can help. I'm just trying to get a TCP socket connection working between a Windows pc server and an android phone. Firstly, how to determine what ip address is needed. I have ATT UVerse Broadband and my pc is connected to its box via ethernet. According to ATT:

https://www.att-services.net/tools/tool-ip-address-hostname.html

I have one ip addr: 162.192.62.91. According to ipconfig, I have another: 192.168.1.67. Both time out calling accept() on the ServerSocket, whether the client is started up shortly after the call or not. Which do I need anyway? Netstat accurately reflects the presence of the server listener until the server code is terminated and then reflects its absence. Not sure what I'm doing wrong. Windows Firewall is currently off. Thanks to anyone who will give it a look. Here's the java server:

package my.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServerSocket {
    static ServerSocket server;
    static String addr = "192.168.1.67";
    static int port = 8080;
    InetAddress ia;
    private MyServerSocket() throws Exception {
        if (addr != null && !addr.isEmpty()) {
            ia = InetAddress.getByName(addr);  //ipAddress);
            System.out.println("18 MSS InetAddress.getByName(" + addr + ") = " + ia);
            try {
                server = new ServerSocket(port, 1, ia);
                System.out.println("20 MSS Nonempty ipAddress: instantiated ServerSocket");
            } catch( IOException e) {
                System.out.println("22 MSS while instantiating ServerSocket: " + e);
            }
        }
        else { 
            ia = InetAddress.getLocalHost();
            server = new ServerSocket(port, 1, ia);
            System.out.print("28 MSS empty ipAddress: MSS new ServerSocket port ");
            System.out.print(port);
            System.out.println(", addr " + ia);
        }
    }

    private void listen() throws Exception {
        String data = null;
        Socket client = server.accept();  //Hangs here
        String clientAddress = client.getInetAddress().getHostAddress();
        System.out.println("35 MSS New connection from " + clientAddress);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(client.getInputStream()));        
        while ( (data = in.readLine()) != null ) {
           System.out.println("40 MSS Message from " + clientAddress + ": " + data);
        }
    }

    public static void main(String[] args) throws Exception {
        MyServerSocket app = new MyServerSocket();
        System.out.println("52 MSS instantiated MyServerSocket: " + 
                " Addr=" + server.getInetAddress() + 
                " Port=" + server.getLocalPort());

        app.listen();
    }
}

Android Client:

package my.androidsocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.util.Log;

public class AndroidClientSocket extends AsyncTask <String, Void, String>{
    private static final String LOG_TAG = "ClientSocket";
    static InputStream is = null;
    private String serverHostOrIPAddr = "192.168.1.67"; //162.192.62.91 (can't assign addr)
        //127.0.0.1 (refused) "listening on port 3306 (mysql) for local loopback only"
        //192.168.1.67 (times out w an Exception) (from cmd->ipconfig-> ip4 address)
    private String serverPortStr = "8080";

    @Override
    protected String doInBackground(String... params) {
        Integer serverPort = Integer.parseInt(serverPortStr);
        Log.d(LOG_TAG,"24 ACS connecting to host " + serverHostOrIPAddr +
                                                " on port " + serverPort + ".");
        Socket socket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            //hangs, then returns null even when server is listening to the addr/port at startup
            socket = new Socket(serverHostOrIPAddr, serverPort);

            System.out.print("33 ACS Socket instantiation returned ");
            System.out.println(socket);

            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String userInput = "a\r\n";
            while (true) {
                System.out.print("client: ");
                //String userInput = stdIn.readLine();
                /** Exit on 'q' char sent */
                if ("q".equals(userInput)) {
                    break;
                }
                out.println(userInput);  //out to console
                userInput = "";
                System.out.println("server: " + in.readLine());  //chars from server
            }

        } catch (UnknownHostException e) {
            Log.d(LOG_TAG,"55 ACS while connecting to host " + serverHostOrIPAddr + ": " + e );
            try {
                socket.close();
            } catch (IOException e1) {
                Log.d(LOG_TAG,"59 ACS while closing socket " + e );
            }
            System.exit(1);
        } catch (IOException e) {
            Log.d(LOG_TAG,"63 ACS while connecting to host: " + e);
            if(socket!=null) {
                try {
                    socket.close();
                } catch (IOException e1) {
                    Log.d(LOG_TAG,"68 ACS while closing socket: " + e);
                }
            }
            System.exit(1);
        }

        String userInput = "user input...\r\n";  //Fake the user console input
        out.println(userInput);
        Log.d(LOG_TAG,"76 ACS user input sent to socket output stream: " + userInput);
        out.close();

        try {
            in.close();
        } catch (IOException e) {
            Log.d(LOG_TAG,"82 ACS IOException closing input stream: " + e);
        }
        try {
            socket.close();
        } catch (IOException e) {
            Log.d(LOG_TAG,"87 ACS IOException closing socket: " + e);
        }
        return "null";
    }

}

and Android caller:

package my.androidsocket;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AndroidClientSocket acs = new AndroidClientSocket( );
        acs.execute();

        TextView tv = (TextView) findViewById(R.id.textView1);
        tv.setText("18 MA GET response: " + "null");
    }
}

And output:

18 MSS InetAddress.getByName(192.168.1.67) = /192.168.1.671
20 MSS Nonempty ipAddress: instantiated ServerSocket: port=8080 bindAddr=/192.168.1.67

Upvotes: 0

Views: 674

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596958

Your server needs to bind to either

  • the specific IPv4 address of the network adapter that is connected to your LAN router (in your case, 192.168.1.67).

  • 0.0.0.0, which binds to all local IPv4 networks that the PC is connected to.

When the phone is connected to a mobile network, it must connect to your public Internet IPv4 address, as assigned by your ISP (in your case, 162.192.62.91).

Since your PC gets its Internet connection from a LAN router, you need to also enable port forwarding in the router's configuration so it can pass inbound traffic from the router's public WAN IP:port to a LAN IP:port that your server is bound to. You are likely missing this step.

If your router supports uPNP and it is enabled, your server code can configure the port forwarding dynamically when needed (see How to port forward automatically in java?). Otherwise, you have to log into your router directly and configure it statically as needed.

When the phone is connected to the same LAN as the PC, it can connect to any LAN IPv4 address that the server is bound to.

Upvotes: 1

Related Questions