I'm trying to fetch data from a web server running on http://localhost:5050 and print it. At first it gave me a Socket Exception, so I looked it up and looks like you're supposed to replace "localhost" with your computer's IP address, so I did that, and now when I fetch it, it just seems to be... stuck? I have a print statement after the request but it doesn't print anything, no error, no output.. nothing. I'm using a Physical device, Here's my code:
class AllFlights extends StatefulWidget {
const AllFlights({Key? key}) : super(key: key);
#override
_AllFlightsState createState() => _AllFlightsState();
}
class _AllFlightsState extends State<AllFlights> {
Future<void> getAllFlights() async {
try {
log("here");
final res = await http.get(Uri.parse("http://192.168.8.100:5050/iflive/atc")); //fetch data -- gets stuck here
log(res.body); // "log" statement, imported from dart:developer
} catch (e) {
log(e.toString());
}
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: ElevatedButton(child: Text("All Flights",), onPressed: getAllFlights,),
),
);
}
}
Note: if it matters, the web server is running in a Docker container on port 5050 mapped to port 5050 on the host.
EDIT: I just noticed that a solid 2-3 mins after calling the api, it gives me a Socket Exception: [log] SocketException: OS Error: Connection timed out, errno = 110, address = 10.0.2.2, port = 44046
Is this normal?
Update: I was able to fix this by using adb (Android Debug Bridge) .
adb reverse tcp:5050 tcp:5050
this command routes your phone's requests on port 5050 to your computer's port 5050. Now you can just make requests to localhost directly instead on your computer's IP. The first port argument is your phone's port and second is your computer's.
example: adb reverse tcp:5000 tcp:5050 will map port 5000 on your phone to 5050 on your computer.
Have a nice day everyone!
Related
I am using lan_scanner flutter package to gather IP Addresses of a network.I want to also get the hostname of each particular address. Any ideas on how can I achieve that?
I tried using some other packages but to no avail.
you can connect to that device and ask for it's hostname
first add a server socket to listen for clients (devices)
const int port = 7575;
try {
ServerSocket server = await ServerSocket.bind(deviceIp, port);
server.listen((client) {
client.listen((data) {
final ip = client.remoteAddress.address;
final hostname = String.fromCharCodes(data);
print("hostname of $ip is $hostname");
});
});
} on SocketException catch(_) {
print('failed to create a server socket');
}
then for each device connect to the server and send the device hostname
try {
Socket client = await Socket.connect(targetIp, port);
client.write(Platform.localHostname);
client.destroy();
} on SocketException catch(_) {
print('failed to connect to the server');
}
In my app, I created a Route for communicating with a socket.
class _SocketRouteState extends State<SocketRoute> {
#override
void initState() {
super.initState();
try {
WebSocketChannel _channel = IOWebSocketChannel.connect(
Uri.parse('ws://192.168.1.90:9998'),
);
///
/// Start listening to new notifications / messages
///
_channel.stream.listen(
(data) {
debugPrint(data);
},
onDone: () {
debugPrint('ws channel closed');
},
onError: (error) {
debugPrint('ws error $error');
},
);
_channel.sink.add('testing');
} catch (e) {
///
/// General error handling
/// TODO handle connection failure
///
debugPrint('Connection exception $e');
}
}
}
When I run this code, it fails to connect to the socket, though. After waiting for ~2 minutes, Xcode shows me the following error:
flutter: ws error WebSocketChannelException: WebSocketChannelException: SocketException: OS Error: Operation timed out, errno = 60, address = 192.168.1.90, port = 52168
This clearly shows a different port. Could that be the issue? Anyone know why it's connecting on port 52168 instead of 9998?
The problem with the confusing port number is, that the error message is not that great, since it shows the local port being used on your own machine and not the remote port you are trying to connect to. TCP requires a port to be open on both the server and the client so they can communicate both ways. But normally, you are mostly interested in the remote port.
There are an old github issue here about this issue:
https://github.com/dart-lang/sdk/issues/12693
I have a server running on a Raspberry Pi which is accessible from a browser.
http://192.168.1.67:55XXX/?email=a#b.com
yields:-
{Order=[{no=0, day_0=1, price=0, name=PPAC SUPERTHERM 20K, display_colour=blue, notice=1, special_order=false}, {no=1, day_0=1, price=0, name=SLACK 50KG , display_colour=blue, notice=1, special_order=false}, {no=0, day_0=1, price=0, name=PPAC SUPERTHERM 20K, display_colour=blue, day_5=1, notice=1, special_order=false, day_3=1}, {no=1, day_0=1, price=0, name=SLACK 50KG , display_colour=blue, day_5=1, notice=1, special_order=false, day_3=1}], Details={address=xx Farriers Lea, phone=0xxxx 606635, name=Fred Bloggs, mobile=, details=end shed on drive, email=a#b.com}}
I am using VSCODE to debug dart code.
my dart code:-
String remote_ip = '192.168.1.67'; //212.159.118.177';
var remote_port = 55XXX;
Socket socket;
String _dataToBeSent = "http://?email=a#b.com\n";
var reply;
// connect
main(List<String> arguments) async {
await _remoteServerConnect();
}
// REMOTE SERVER CONNECT
Future _remoteServerConnect() async {
// await Socket.connect(remote_ip, remote_port).then((Socket sock){
await Socket.connect(remote_ip, remote_port).then((Socket sock) {
socket = sock;
print('Got connected ${socket.remoteAddress}');
socket.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
}).catchError((AsyncError e) {
print("Unable to connect: $e");
exit(1);
});
}
void dataHandler(data) async {
await print('"'+String.fromCharCodes(data).trim()+'"');
if (String.fromCharCodes(data).trim().endsWith('html')) {
print("Send Data = $_dataToBeSent");
socket.add(utf8.encode(_dataToBeSent));
// socket.writeln(_dataToBeSent);
socket.flush();
await Future.delayed(Duration(seconds: 5));
}
}
void errorHandler(error, StackTrace trace) {
print(error);
}
void doneHandler() {
// socket.destroy();
exit(0);
}
The dart debug consol yields:-
Connecting to VM Service at ws://127.0.0.1:54799/kE9Xa1JQclk=/ws
Got connected InternetAddress('192.168.1.67', IPv4)
"HTTP/1.1 200 OK" <sent by server
"ContentType: text/html" <sent by server
Send Data = http://?email=a#b.com
Exited
The server consol yields:-
Server is ready
WEB Client connected: /192.168.1.66
05.08/10:34:21.17 - Waiting for command..
05.08/10:34:31.80 - Socket Timeout
05.08/10:34:31.82 - Done -------------
05.08/10:34:31.82 - Waiting for command..
Connection has been closed
Server is ready
It would seem the
socket.add(utf8.encode(_dataToBeSent));
// socket.writeln(_dataToBeSent);
socket.flush();
did not send data to the server?? Why?? any ideas gratefully received!
Disabling my dev machines firewall did NOT improve answer!
Steve
The server used
final DataInputStream in = new DataInputStream(clientSocket.getInputStream());
while (estimatedTime < 60000) {
report("Waiting for command..");
try {
// in.readNBytes(command.data, 0, command.length);
in.readFully(command.data);
to receive the data command.data is 100bytes long so was waiting for the complete input. I padded to 100 bytes worked fine - will sort a better solution later.
I'm trying to write a flutter app for an IoT application. A mobile device will connect to the hardware via WiFi and data will be sent through a tcp socket. The IoT hardware is in development but I need to get a start on the app.
I got some help with a python script that runs a socket and outputs 2 sine waves that have been slightly randomized. It works well and I have a python host script that connects to it and plots the data as it comes through. I am going to pretend this is sensor data so I want to connect to this with flutter so that I can start working on my UI etc.
I've tried 1000 things but mostly worked through this: https://flutter.dev/docs/cookbook/networking/web-sockets.
Another thing I tried was using nodejs with socket.io and did manage to communicate with flutter using the adhara_socket_io package but there is so much abstracted away there that I worry its not replicating what I'll get from our hardware.
Here is the python code:
import queue
import time
#import matplotlib.pyplot as plt
import math
from queue import Queue
import numpy as np
import random
import socket
import threading
import asyncio
# A Queue in which the wave threads will store their values
# We will use this queue to get the data we need to send to our clients
Q = queue.Queue()
# replace this with your own host ip
HOST = '192.168.0.13'
PORT = 65432
Afrequency = float(input('give the frequency of the data output wave A: '))
Aperiod = int(input('give the output period (multiples of pi) of wave A: '))
Bfrequency = float(input('give the frequency of data output wave B: '))
Bperiod = int(input('give the output period (multiples of pi) of wave B: '))
# this function will continuosly generate x and y values for a given sine wave
# it waits 1/freq seconds so our frequency matches the given input
def generateTuples(name, outputfrequency, outputperiod):
sincurveshift = 10
rmax = 1.25
rmin = 0.75
outputperiod = outputperiod * math.pi
numberOfPoints = outputfrequency * outputperiod
increment = (2 * math.pi) / numberOfPoints
xcounter = 0
while True:
jitterValue = rmin + (random.random() * (rmax - rmin))
x = xcounter * increment
sinValue = 5 * math.sin(x) + sincurveshift * jitterValue
partOfTheMessage = '%s(%09.2f,%09.2f)*' % (name, x, sinValue)
xcounter += 1
Q.put(partOfTheMessage)
time.sleep(1/outputfrequency)
# this is a thread that will be created each time a client connects
# it sends the total string with values from wave A and B
class clientThread(threading.Thread):
def __init__(self, clientAddress, clientSocket, q):
threading.Thread.__init__(self)
self.clientSocket = clientSocket
print("New client connected with address: " + str(clientAddress))
def run(self):
while True:
self.clientSocket.send(bytes(Q.get(), 'utf-8'))
time.sleep(0.1)
def main():
# first we start up 2 threads that will each generate a y value every 1/freq seconds
# we let them run in the background so we can move on to listening for clients
print('starting sine wave 1')
print('starting sine wave 2')
wave1 = threading.Thread(target=generateTuples, args=(
'A', Afrequency, Aperiod), daemon=True)
wave2 = threading.Thread(target=generateTuples, args=(
'B', Bfrequency, Bperiod), daemon=True)
wave1.start()
wave2.start()
time.sleep(1)
print('starting transmission')
# here we set up the host
# we continously look for clients and give each of them their own thread
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen()
while True:
conn, addr = s.accept()
client = clientThread(addr, conn, queue)
client.start()
if __name__ == "__main__":
main()
And here is my flutter code.
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'MyApp Mobile'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final channel = IOWebSocketChannel.connect('ws://192.168.0.13:65432');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: StreamBuilder(
stream: channel.stream,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.none:
print('trying to connect');
return LinearProgressIndicator();
case ConnectionState.active:
print("OMG ITS CONNECTED");
print(snapshot.data);
return Text(snapshot.data);
case ConnectionState.done:
return Text('Its done ${snapshot.data}');
}
return Text(snapshot.hasData ? '${snapshot.data}' : 'No Data');
},
)),
);
}
}
I'm using my phone to run the app in development - not sure if that counts for anything.
Any help is greatly appreciated!
N
EDIT -
I'm now seeing an error in the python console:
New client connected with address: ('192.168.0.16', 65020)
Exception in thread Thread-24:
Traceback (most recent call last):
File "C:\Users\nickc\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "host.py", line 62, in run
self.clientSocket.send(bytes(Q.get(), 'utf-8'))
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
So it looks like it connects and then aborts the connection?
Like already mentioned by shubham in one of the answers I can sucessfully connect and print the incoming data to the console with:
Socket socket = await Socket.connect(host, port);
socket.listen((event) {
print(String.fromCharCodes(event));
});
I don't have much knowledge on the web socket channel package but when I tried running your code, I got broken pipe error on the python code as soon as my client(phone) connected and after going through this post I think the client socket is getting closed somehow.
But I am able to connect to your python socket using dart's socket package
Here is the code
Socket socket = await Socket.connect(host, port);
socket.listen((event) {
log(String.fromCharCodes(event));
});
Here is the output that I got
[log] B(000051.07,000013.89)*
[log] B(000051.11,000013.26)*
[log] B(000051.14,000016.09)*
[log] B(000051.18,000013.77)*
[log] B(000051.21,000015.63)*
[log] B(000051.25,000013.78)*
[log] B(000051.29,000013.49)*
[log] B(000051.32,000016.75)*
[log] A(000103.50,000012.36)*
[log] A(000103.58,000009.93)*
[log] A(000103.67,000007.72)*
[log] A(000103.75,000009.02)*
[log] A(000103.83,000008.28)*
Im trying to connect to Openfire Server using Asmack library 4.0.2.Im failing to get connected to the server even though i had provided correct ip address with the port.
public static final String HOST = "192.168.1.100";
public static final int PORT = 9090;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect();
}
public void connect(){
AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>(){
#Override
protected Boolean doInBackground(Void... arg0){
boolean isConnected = false;
ConnectionConfiguration config = new ConnectionConfiguration(HOST,PORT);
config.setReconnectionAllowed(true);
config.setSecurityMode(SecurityMode.disabled);
config.setDebuggerEnabled(true);
XMPPConnection connection = new XMPPTCPConnection(config);
try{
connection.connect();
Log.i("XMPPChatDemoActivity","Connected to " + connection.getHost());
isConnected = true;
} catch (IOException e){
Log.e("XMPPIOExceptionj", e.toString());
} catch (SmackException e){
Log.e("XMPPSmackException", e.toString()+" Host:"+connection.getHost()+"Port:"+connection.getPort());
} catch (XMPPException e){
Log.e("XMPPChatDemoActivity", "Failed to connect to "
+ connection.getHost());
Log.e("XMPPChatDemoActivity", e.toString());
}
return isConnected;
}
};
connectionThread.execute();
}
And im getting the following error possibly because Host and Port are getting assigned null and 0 respectively even though i had assigned them correctly.Pls help me in
sorting out this connection prob.
08-12 22:10:20.496: E/XMPPSmackException(4341):org.jivesoftware.smack.SmackException$NoResponseException Host:nullPort:0
Can you confirm that port 9090 is the correct port for XMPP protocol? Default install of Openfire will set port 9090 to be used for accessing the HTTP based configuration console. I recommend you try connecting to the port for XMPP connections as specified on the main index page of the Openfire configuration console (Listed below "Server Ports").
The following is taken from the Openfire configuration console:
5222 The standard port for clients to connect to the server. Connections may or may not be encrypted. You can update the security settings for this port.
I think your Host adress is wrong too, you must use the adress to connect openfire server. It must be "127.0.0.1" or just write "localhost". and the port is 5222 to be able to talk from client to server.