Why does my Java app for Android not connect to the server?
I run the application in Android emulator, and the server which is on port 9999 and host 127.0.0.1 in my pc, but it will just not connect and I think this method isn't good for Sndroid app.
Update: I work with API 8 and Android 2.2
This is my source code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
//Java imports
//import android.util.Log;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainActivity extends Activity{
//Variaveis Interface
private Button ligar;
private Button enviar;
private EditText text1;
private TextView text2;
//Variaveis
static Socket cSocket;
static PrintWriter out;
static BufferedReader in;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Declaração butões
ligar = (Button) findViewById(R.id.ligar);
enviar = (Button) findViewById(R.id.enviar);
text1 = (EditText) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);
//Interacao
ligar.setOnClickListener(new OnClickListener(){
public void onClick(View arg0){
connect();
}
});
enviar.setOnClickListener(new OnClickListener(){
public void onClick(View arg0){
out.println("Hello");
text2.setText("");
}
});
}
//Outras Funcoes
public void connect(){
//Funcao ligar
cSocket = null;
out = null;
in = null;
try{
cSocket = new Socket("10.0.2.2",4444);
out = new PrintWriter(cSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
text2.setText("Estas conectado com sucesso.");
}
catch (IOException ex) {
//Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
text2.setText("Erro! Na conexão");
}
}
//
}
Also note that the address 127.0. 0.1 on your development machine corresponds to the emulator's own loopback interface. If you want to access services running on your development machine loopback interface (a.k.a. 127.0. 0.1 on your machine), you should use the special address 10.0.
The default value is 5554 for the first virtual device instance running on the your machine. A virtual device normally occupies a pair of adjacent ports: a console port and an adb port. The console of the first virtual device running on a particular machine uses console port 5554 and adb port 5555.
If you're using Android Studio to run the emulator, then localhost of your host computer will be mapped to the IP address, 10.0. 2.2 , inside the emulator. If you're using other programs to run the emulator, then you may need to consult the documentation associated with those programs.
See here:
Host machine can be reached using IP address 10.0.2.2
from the emulator.
**edit, answer to your comment:*
For completeness and to better understand my answer, read the Android Emulator documentation.
These are the IP addresses as reached from the emulator:
10.0.2.1
, Router/gateway address.10.0.2.2
, Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine)10.0.2.3
, First DNS server10.0.2.4
/ 10.0.2.5
/ 10.0.2.6
, Optional second, third and fourth DNS server (if any)10.0.2.15
, The emulated device's own network/ethernet interface
127.0.0.1
, The emulated device's own loopback interface
That said, we have:
127.0.0.1
from the emulator trying to reach your host machine. Use 10.0.2.2
, as I said.HostComputerIP:appServicePort
. It won't work since your host computer itself (Windows, Linux, OS etc.) is not running a service in that port. You need to redirect a port on the emulator console to a port on an emulated Android instance itself (see 2 below).Common networking needs:
1- Emulator app as client and local computer as server
Because the emulator is NAT'd, I believe you can connect to any computer on your local network directly. I mean, since the virtual router has access to both networks, it should be able to handle outgoing (i.e., emulator->real lan) connections just fine.
Example: on my network (192.168.0.x), I can connect from the emulator to my real router (192.168.0.254
) just pointing the emulator web browser to http://192.168.0.254:port
. I use different services on it (hail to Tomato!), and I can access all of them on each port
. No need to handle port forwarding, as expected.
By the looks of your code, I believe you need:
// I assume 192.168.0.114 is your server, which is
// located on your local network, running a server application
// on port 9999.
cSocket = new Socket("192.168.0.114",9999);
2- Local computer as client and emulator app as server
Now that's a different story. You need to setup port redirections on the virtual router. The easiest way is:
Telnet into the "management" system (this is not the emulator), from your host (your computer, console on linux or command prompt on Windows):
telnet localhost 5554
After that, use:
adb forward tcp:localPort tcp:emulatorPort
After this, you will be able to have a service on emulatorPort
and you will be able to connect to it from computers in the local network by accessing hostComputerIP:localPort
.
This is the way people (including me) use, for example, SSHDroid inside an emulator.
Anything else?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With