Flutter can not create TCP SOCKET for P2P connection - android

I'm aiming to make a p2p chat app with Flutter/Dart. My Concept is: There are peers and a server. Server only works for peers to find each other. After 2 peers find each other, they will connect to each other via Socket and will have nothing to do with server. They'll handle rest (messaging part) via their own sockets. I made server part. Peers successfully connects to server and send informations (IP and PORT number which is used in creating it's own Socket). The problem is, a peer can't connect to another.
I mean, lets assume we have Peer A and Peer B. Peer A's IP is 155.252.100.13(Public ip) and Port number used for socket is 12456 (I've just made up these numbers, they are not real)
The code I used in peer a is this:
(Peer A runs on an emulator, it has connection to the Internet I checked)
final Future<ServerSocket> mySocket = ServerSocket.bind("0.0.0.0", 12345);
then, Peer B tries to connect it like this:
(Peer B runs on physical Android Device. I connected it to Android studoio via USB cable)
p2pSocket = await Socket.connect("155.252.100.13", 12345);
and I get error on Peer A:
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: StreamSink is closed
#0 _StreamSinkImpl.add (dart:io/io_sink.dart:134:7)
#1 _Socket.add (dart:io-patch/socket_patch.dart:2203:38)
#2 main. (package:encrypt/peer.dart:225:24)
#3 _RootZone.runUnaryGuarded (dart:async/zone.dart:1586:10)
#4 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#5 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#6 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#7 _StreamController._add (dart:async/stream_controller.dart:648:7)
#8 _StreamController.add (dart:async/stream_controller.dart:596:5)
#9 _Socket._onData (dart:io-patch/socket_patch.dart:2324:41)
#10 _RootZone.runUnaryGuarded (dart:async/zone.dart:1586:10)
#11 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#12 _BufferingStreamSubscription._add (dart:async/stre<…>
Sometimes I don't get any error on peer A. peer B just doesn't connect. No error message. Just does nothing. Comes to connect line and waits forever or stops I don't know.
What's wrong? The hall idea? Or technique? What should I do?

Related

Dart/Flutter sockets connects on random port

Modern programming is turning more and more frustrating. Trying to do a simple socket test app on Flutter (tested on Android). Code is simple and self explanatory:
void Connect()
{
print("connecting...");
Socket.connect("localhost", 80).then((Socket sock) {
socket = sock;
socket?.listen(dataHandler,
onError: errorHandler,
onDone: doneHandler,
cancelOnError: false);
socket?.write("GET / HTTP/1.1");
}).catchError((Object e) {
print("Unable to connect: $e");
});
}
Code throws exception. Output:
I/flutter (15930): connecting...
I/flutter (15930): Unable to connect: SocketException: OS Error: Connection refused, errno = 111, address = localhost, port = 47244
The port is always different, why TF is that happening?
The port number in the error message is the local port and not the remote port. There are an issue about this problem here: https://github.com/dart-lang/sdk/issues/12693
In short, when connecting using TCP, you need two ports. One local which is open on your device and one remote which is the port open on the system you are trying to call. After a connection is established, the communication is going between this two port numbers.
So the error indicates that your server running on localhost:80 is refusing the connection from your application. The local port number in the error message can often just be ignored since it is not really relevant to debug most issues.

How can I tell if I'm still listening on a socket in Android

I'm responsible for some code on an Android device which talks to a PC over WiFi via a wireless access point (WAP), using TCP sending packets back and forth. On the PC side the software uses winsock to send and receive packets with the Android device, but I have no access to, or control over, the PC side of this connection.
This architecture works fine sending and receiving, but if there is no traffic for exactly 1 minute, then if the PC attempts to send a packet to the Android it gets an RST back, as though the Android is no longer listening. Winsock, on the PC side, is interpreting this is a timeout.
The Android device is configured to keep the WiFi "always on". I'm using a java.net (Android API 16) socket in my code. Is there something I can check on that socket periodically, or an event I can receive to see if I've stopped listening?
(Edit) I'm specifically referring to whether the Android is listening. After 1 minute the Android device can still send. Here's a Wireshark trace that illustrates this:
11 10.1.2.1 10.1.2.11 TCP 79 42825→181 [PSH, ACK] Seq=1 Ack=1 Win=8170 Len=13 7
12 10.1.2.11 10.1.2.1 TCP 89 181→40574 [PSH, ACK] Seq=1 Ack=14 Win=259 Len=23
13 10.1.2.1 10.1.2.11 TCP 60 40574→181 [RST] Seq=14 Win=0 Len=0
The Android is 10.1.2.1, the PC is 10.1.2.11. In this example I initiated a send from the Android TO the PC, and it went just fine. The PC tried to send something in response, but the Android sent an [RST]
Also N.B. that this only refers to TCP - if the PC tries to ping the Android after 1 minute it still gets a response, but ping is ICMP.
Edit 2
Someone wanted to see how I create the socket. So here it is:
new SocketPermission(new String(new StringBuilder(configLGIP).append(":180-")), "connect,accept,listen");
// Open a socket to the front end
Log.d("StartTCP", "attempt IP " + configLGIP);
try {
sock = new Socket(configLGIP, 180 + SafeActivity.pdanum);
}
Later I do...
if (sock != null) try {
sock.setTcpNoDelay(true);
bin = new BufferedInputStream(sock.getInputStream());
You have to Communicating Devices.
Android Device
and PC
Your android device is sending a RST Flag which means, that no service available on the addressed Port.
Programmatically In Order to detect such FLAG and respectively the unavailable Service,
create your own TCP Datagram by implementing a raw socket interface.
In this Case you can analyse the headers of the Datagram. Implementing such Socket require an administrative privileges (which i think you have on the PC side).
Here's more infos hier !
Hope I can help

32feet gives me an exception if I send and receive at the same time

Im using 32feet to connect to an android phone with bluetooth. Both the phone and the pc have a bluetooth (bt) client and a server running. Everything works fine if I do only a send or a receive, but if I do a send on both sides at the same time, on the pc I get an exception.
In other words, this is what needs to happen simultaneously for me to get an exception.
BT Client PC * -------> BT Server Android (pc client gets exception)
BT Server PC <------- BT Client Android (everything is fine every time (message is received))
(*) Exception, android doesn't see the connection attempt
This is the exception:
System.Net.Sockets.SocketException (0x80004005): An invalid argument was supplie
d 083D88459AE0:1c556c4d4d9a422691cfff53d3634cd3
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddre
ss socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at InTheHand.Net.Bluetooth.Msft.SocketBluetoothClient.Connect(BluetoothEndPoi
nt remoteEP)
at InTheHand.Net.Sockets.BluetoothClient.Connect(BluetoothEndPoint remoteEP)
at BluetoothClientTest.Program.Main(String[] args) in C:\gyozo\testprojects\B
luetoothClient\BluetoothClient\Program.cs:line 37
I don't know what is wrong. Any help is appreciated.

Bluecove on PC cannot detect connected android (galaxy tab 7.0)

I use this code
luugiathuy.com/2011/02/android-java-bluetooth/
The server side is the PC
the client is the device, with the app based on bluetooth chat example
The device (galaxy tab 7.0) can establish connection with the PC.
However the PC server (written in java and bluecove) did nothing, as nothing is connected.
The loop for trying to find connected device is
while(true) {
try {
System.out.println("waiting for connection...");
connection = notifier.acceptAndOpen();
Thread processThread = new Thread(new ProcessConnectionThread(connection));
processThread.start();
} catch (Exception e) {
e.printStackTrace();
return;
}
Output on PC:
uuid: 0000110100001000800000805f9b34fb
waiting for connection...
EDIT: source downloadhttps://github.com/luugiathuy/Remote-Bluetooth-Android
Same issue I got when I was trying in linux. But the reason (still not sure) when you run the bluetooth android application without turning on the Java server using bluecove, It will try to connect with the already installed bluetooth software. You may see the bluetooth icon asking for granting access to the mobile device.
To solve this, I just changed the uuid in the server and application (say from 1103 to 1101 and vice versa) and then started the server first and then the android application. Java server part started listening.
The reason I think may be the uuid when it did not found the bluecove stack service server, it got connected to the device server listening on same uuid. So after changing the uuid and making sure that the server is running before launching the android application should solve the issue.
If you are getting connected to the bluetooth system application and not to the Java bluecove server,
1) First change the uuid both server and android application.
2) Second make sure your server is running and listening on same uuid.
3) Launch the android application which try to communicate on same rfcomm connection uuid.
Server part code I took from : http://www.jsr82.com/jsr-82-sample-spp-server-and-client/
Library : http://code.google.com/p/bluecove/downloads/list
Yes, it happens with me too, I suggest you to fire following commend on shell, when it shows waiting for connection.
hcitool cc 58:C3:8B:D7:FA:F4
here 58:C3:8B:D7:FA:F4 is my device's bluetooth address, which should be replaced by your device's bluetooth address.
To get your device's bluetooth address, just start bluetooth in your device with discoverable mode and execute hcitool scan command, it will display all the active device with their name and bluetooth address.
Well you may run the above hcitool cc 58:C3:8B:D7:FA:F4 command via Java code as follows,
try
{
Process p=Runtime.getRuntime().exec("hcitool cc 58:C3:8B:D7:FA:F4");
}
catch ( Exception e )
{
}
The output from your program says it listens on UUID 0x1101. Is that true? The sample you reference shows it listening on a different UUID. Its Service Class Id is 0x04c6093b and is set as follows:
34 UUID uuid = new UUID(80087355); // "04c6093b-0000-1000-8000-00805f9b34fb"
35 String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
36 notifier = (StreamConnectionNotifier)Connector.open(url);
The two need to match on client and server.

Cleaning up failed UUID channel lookup

when opening a bluetooth rfcomm socket via the UUID method ( the other method ( using reflection ) in here http://code.google.com/p/android/issues/detail?id=5427 ) - I sometimes get the following error ( after successfull connections ) and the socket is not opened:
E/BluetoothService(21847): Received ACTION_UPDATE_SERVICE_CACHE00:0B:CE:01:2E:00
D/BluetoothService(21847): updateDeviceServiceChannelCache(00:0B:CE:01:2E:00)
D/BluetoothService(21847): Cleaning up failed UUID channel lookup: 00:0B:CE:01:2E:00 00001101-0000-1000-8000-00805f9b34fb
had no luck with google on this one - has anyone here a clue whats going on and how to prevent that?
Update:
for people running into the same problem - possible solutions:
advice the users to reboot the device if we run into that state (
very bad UX )
use the reflection method ( dirty but works most of the time )
I am still open for new Ideas ;-)
I stick to #2 at the moment - but waiting for a better solution.
It seems that the message is the consequence, not the reason. If a serial port emulation service is not found on device the connection will obviously fail.
Update
After reviewing code everything seems ok. So my questions are: Do the random errors occur with same device o with different devices? If the occur with different devices, the devices might have not registered the SerialPort service. Is device previously paired? In case of the error ocurring randomly with same device? Are you using the connection class concurrently? You have not protected the methods against concurrent access. You have not protected either against succesive connects. If you try to read/close a stream after a second connect it will fail (the socket object has changed).
It seems ok. The random error occurs with same device? If this is the case, are you using concurrent use of that class? In first case

Categories

Resources