2

Environment

  • Android Studio latest release
  • Android Emulator running Android Nougat
  • MAMP to serve as HTTP server

Problem

My simple method

  Future<String> _getSimpleReply( String command, callback, errorCallback ) async {

    try {

      HttpClientRequest request = await _myClient.get( '127.0.0.1', 80 '/' );
      HttpClientResponse response = await request.close();
      await callback( response.toString() );

    } on SocketException catch( e ) {

      errorCallback( e.toString() );

    }

  }

fails with an error:

cbLoginFailed :: SocketException: OS Error: 
  Connection refused, errno = 111, address = 127.0.0.1, port = 46414

Currently using the Android emulator, which has been configured for internet access:

<uses-permission android:name="android.permission.INTERNET"/>

For test purpose, the HTTP server is MAMP, which executes the index.php script and returns some simple string, if I enter this link in a browser:

http://127.0.0.1/index.php

The situation does not change, if I replace 127.0.0.1 with localhost.

But if I do change 127.0.0.1 with a valid public FQDN, the method works just fine:

doLoginSuccess :: Instance of '_HttpClientResponse'

Question

  1. Why does the android emulator / flutter / dart handles 127.0.0.1 different than a valid FQDN?

  2. And how to I change this behaviour?

SteAp
  • 11,853
  • 10
  • 53
  • 88
  • 2
    Are you aware that `127.0.0.1` means `localhost` which is the device/emulator itself for code executed on the phone? See also https://stackoverflow.com/questions/49855754/unable-to-make-calls-to-localhost-using-flutter-random-port-being-assigned-to-h/49855877#49855877 – Günter Zöchbauer Jul 22 '18 at 16:49
  • 1
    @GünterZöchbauer LOL! Minutes ago I missed that point ;-) – SteAp Jul 22 '18 at 16:52

2 Answers2

4

As pointed out by the first comment, localhost or 127.0.0.1 is - when running an app on Android emulator - in fact the local machine on which the Android app is executing. With respect of the Android app, the local machine is the emulated Android system.

Therefore, the http request from the flutter code doesn't leave the emulator at all. Since the Flutter app doesn't provide a HTTP Server, the emulator refuses the http request.

Need to change to the address of the host machine, on which the emulator is executing.

The Android emulator uses special IP addresses to communicate with its host or the host gateway.

Habe a look in the Android documentation.

E.g., the host‘s loopback Interface is identified by this IP: 10.0.2.2 So, if normally one would use 127.0.0.1:80, one can substitute it with 10.0.2.2:80.

Joel G Mathew
  • 7,561
  • 15
  • 54
  • 86
SteAp
  • 11,853
  • 10
  • 53
  • 88
  • I still didn't get this I am running a npm server on my windows at port 3000 I get a json response at localhost:3000/api in my browser ,so the http request should be sent to which addresss 10.0.2.2 or IP address of my local machine when my client is the android emulator – Mahesh Jamdade Feb 02 '19 at 12:40
2

You are trying to access localhost which is your phone/emulator not your PC which I assume is running your test server. You need to create a network between your PC and phone and use the local IP address instead

Conscript
  • 607
  • 6
  • 21
  • If the app is running on an android emulator, wouldn't be the IP of the host Mac just fine? In fact, fails to connect too. – SteAp Jul 22 '18 at 17:14
  • No, creating a network between the emulator and the host system isn‘t necessary. It‘s just a special IP. – SteAp Jul 22 '18 at 18:55
  • Yes, indeed I was mentioning the physical devices, for more info on android emulator networking, you can refer to https://developer.android.com/studio/run/emulator-networking – Conscript Jul 23 '18 at 18:16