Unable to make calls to Localhost using Flutter, random port being assigned to HTTP GET call
Asked Answered
R

2

13

I'm attempting to build a Flutter app where I'm required to make an HTTP call using the dart http library. So here's a snipped of the fu I use to make the call,

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

Future<List> getData() async {
    List data = new List();
    var httpClient = new HttpClient();
    var request = await httpClient.get("localhost", 5000, '/search?query=hello');
    var response = await request.close();
    if (response.statusCode == HttpStatus.OK) {
      var jsonString = await response.transform(utf8.decoder).join();
      data = json.decode(jsonString);
      print(data);
      return data;
    } else {
      return data;
    }
  }

now on calling getData() from my code, here's the error I get

E/flutter (30949): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (30949): SocketException: OS Error: Connection refused, errno = 111, address = localhost, port = 46999
E/flutter (30949): #0      _HomePageState.getData (file:///home/bholagabbar/AndroidStudioProjects/fnd_modile_client/lib/main.dart:75:19)
E/flutter (30949): <asynchronous suspension>
E/flutter (30949): #1      _HomePageState.build.<anonymous closure> (file:///home/bholagabbar/AndroidStudioProjects/fnd_modile_client/lib/main.dart:56:15)
E/flutter (30949): #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:478:14)
E/flutter (30949): #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:530:30)
E/flutter (30949): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
E/flutter (30949): #5      TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:161:9)
E/flutter (30949): #6      TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:94:7)
E/flutter (30949): #7      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9)
E/flutter (30949): #8      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
E/flutter (30949): #9      PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
E/flutter (30949): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:143:19)
E/flutter (30949): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
E/flutter (30949): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
E/flutter (30949): #13     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
E/flutter (30949): #14     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
E/flutter (30949): #15     _invoke1 (dart:ui/hooks.dart:134:13)
E/flutter (30949): #16     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:5)

My API is up and running correctly, As you can see in the error logs, the request just doesn't seem to be going through. What exactly is the issue here?

For the record, I have tried every permutation of get, getUrl and even tried replacing localhost and 127.0.0.1 with 10.0.2.2 as mentioned in How to point to localhost:8000 with the Dart http package in Flutter? . I am testing this on my phone directly (One Plus 3)

Rakehell answered 16/4, 2018 at 11:4 Comment(1)
If you are experiencing the issue on iOS, refer to https://mcmap.net/q/183265/-flutter-iphone-http-port-assigned-randomlyGeis
W
30

This should do it

adb reverse tcp:5000 tcp:5000

https://developer.android.com/studio/command-line/adb.html

Or use adb reverse --list to see what redirects are set up.

Windlass answered 16/4, 2018 at 11:11 Comment(9)
The port is in use? I can't forward abd and have the API running on the same port..atleast that;s the errorRakehell
I think that should be possible. See also my updated answer (adb forward --list)Underweight
adb forward tcp:5000 tcp:5000 adb server is out of date. killing... * daemon started successfully * -> adb forward tcp:5000 tcp:5000 adb server is out of date. killing... * daemon started successfully * for the Python APIRakehell
Looks like I mixed things up. I think it should be reverse instead of forward adb reverse tcp:5000 tcp:5000Underweight
it's so stupid now that I think of it. The localhost that android would be trying to access would be itself.Rakehell
Sorry for not mentioning it, but yes, that's why the redirection is required. You're not the first one falling into that trap :DUnderweight
Haha I'm glad to know that, it's my first time developing on mobile and I'm required to start off straight with flutter. Thanks!Rakehell
Thanks a lot! you saved me! but I wonder why does this happen? can you explain? I'm using flutter and found this nowhere..Connolly
That's not Flutter related at all. If you access localhost from an app running on the emulator it accesses the loopback network interface of the OS running inside the emulator. If you want to access another machine, then you can't use localhost. My answer is a workaround to redirect access to localhost:5000 to port 5000 on the machine the emulator is running on. You could also expose the server you try to access to the public IP interface and use that IP in your Flutter app instead of localhost, but that might be cumbersome for example if you use DHCP and the IP keeps changing.Underweight
A
9

Günter's answer is correct, but one thing you need to keep in mind, that don't forget to change port number For example if your port is 3002 then use:

adb reverse tcp:3002 tcp:3002

Keep in mind that above mentioned command is redirecting your phone's port 3002 to your computer's port 3002.

If you want to redirect your phone's port 3000 to your computer's port 3002 then the command would look like

adb reverse tcp:3000 tcp:3002

More general answer is:

adb reverse tcp:<Your Phone's Port No.> tcp:<Your Computer's Port No>
Arvizu answered 12/3, 2020 at 12:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.