9

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");
   }                
   }
//
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
FredVaz
  • 423
  • 3
  • 8
  • 14
  • Don't forget to mark the answer as accepted, or post your own solution (in case the answers below didn't solve your problem) and accept it. Whenever you solve your problem, you should "finalize" the question marking one answer as "accepted". – davidcesarino Nov 20 '11 at 18:17

2 Answers2

20

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 server
  • 10.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:

  • Common mistake 1: accessing 127.0.0.1 from the emulator trying to reach your host machine. Use 10.0.2.2, as I said.
  • Common mistake 2: Trying to access an emulator service on 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?

Community
  • 1
  • 1
davidcesarino
  • 16,160
  • 16
  • 68
  • 109
  • Yep this is correct, I pulled my hair out for a while on this issue once. – Jack Nov 19 '11 at 04:41
  • Not work... and a already test with a wirelless link, the emulador in a diferent pc that Server ! – FredVaz Nov 19 '11 at 13:59
  • You should have told that it's in a different pc than the server. You said "host 127.0.0.1 in *my* pc", so we guessed it was the same. Anyway, I updated the answer with two solutions for your problem, depending on what *exactly* you want to do. – davidcesarino Nov 19 '11 at 17:57
  • No, it's the same.. but i already test in different pc that emulator.. sorry my bad english. – FredVaz Nov 19 '11 at 18:28
  • No problem about the English. So... answer YES/NO to me: 1) your code is in the emulator, 2) your server is in the local network, 3) your server is *NOT* in the same machine as your emulator. --- Is that right? – davidcesarino Nov 19 '11 at 18:35
  • Não entendi, então vou falar português mesmo. Antes você disse "the emulador in a diferent pc that Server", agora você disse "[server] is the same machine". Se está no mesmo computador, use 10.0.2.2. Se ainda assim você não consegue é porque tem algum problema de firewall ou alguma coisa está errado no seu computador. – davidcesarino Nov 19 '11 at 19:56
  • Sim disse, mas disse que foi só um teste que fiz,e não funcionou... sim, eu conheço o 10.0.2.2, mas já vou testar melho. Obrigado – FredVaz Nov 19 '11 at 20:21
2

127.0.0.1 goes to localhost. While that is your own computer from your PC, it's the phone from the phone. You need to provide the actual IP address. Additionally, if you haven't already set it, make sure you request the Internet permission. See the doc on permissions and this other SO post.

Update: To answer your comment, as David points out from the emulator you can use 10.0.2.2 to reach your host machine.

Community
  • 1
  • 1
kabuko
  • 36,028
  • 10
  • 80
  • 93
  • 127.0.0.1 goes to local host of android or my windows pc ! I test my app in android emulator e server in windows that run emulator.. you understand ?;) – FredVaz Nov 19 '11 at 01:56
  • the android emulator is a virtual machine, so the 127.0.0.1 refers to the localhost of the android emulator S.O itself. – Jordi Coscolla Nov 19 '11 at 02:01
  • okay.. i understand ! So how can i test? Or what Ip host i can use in android to connect server ? – FredVaz Nov 19 '11 at 02:07