-
Notifications
You must be signed in to change notification settings - Fork 1.7k
dart::io::RawSocket is unexpectly closed on iOS during the data reception #47888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @lrhn! is there any updates regarding this issue? If you need any additional information or logs, please let me known! |
Adding the VM people, since they are maintaining the |
sorrry @mkulesh , this felt through the cracks. 1.22.6
later one
Are there any events in the log that indicate that raw socket stayed open longer in 1.22.6? |
@mkulesh wrote
Having physical Onkyo receiver available makes this harder to reproduce. Were you able to further this repro so it doesn't require the receiver? |
Hi @aam,
Yes, the only difference between Flitter 1.22.x and 2.x is the additional log line RawSocketEvent.readClosed, which indicates that RawSocketEvent.readClosed event was suddenly called: void _onEvent(RawSocketEvent event)
{
switch (event) {
case RawSocketEvent.read:
if (_socket.available() > 0)
{
print("RawSocketEvent.read: " + _socket.available().toString());
_onData(_socket.read());
}
break;
case RawSocketEvent.write:
break;
case RawSocketEvent.readClosed:
print("RawSocketEvent.readClosed");
break;
case RawSocketEvent.closed:
break;
default:
throw "Unexpected event $event";
}
} For the app it has an effect that socket is suddenly closed and can not be used anymore.
Not in this example. During test, I just waiting a couple of minutes after the first data packet is received and logged. I have never observed the readClosed event in 1.22.6.
Unfortunately yes, you are right. Using shodan.io, it is possible to find some public onkyo devices in Internet (search string: onkyo), but both versions of Flutter are working stable on all these devices. I believe this is a kind of timing problem, since onkyo receiver in the local network answers connection really fast. When connection is open while the receiver is in standby, it immediately sends a portion of status information and the socket closes. If we try to connect any device in the internet, there is a delay between connection and data reception due to global latency and the socket still be open. When the receiver in the local network is playing something, there is also a delay between the connection and first data reception and the socket still be also alive. It is possible that some timings are changed between Flutter 1.22.x and 2.x? I also tried my HTR with iPhone 7, the behavior is the same as with iPad. If you need any kind of technical logging or additional information, I will be happy to collect it for you. |
Hi @aam,
i.e a single pair "Connection from/Client left" is logged for each app resume
In my server emulator, I skipped to implement the logic that closes all connections when two or more connections from the same remote host on the same server port are detected. Therefore, app still be always connected. But, again, a real Onkio/Pioneer receiver do it.
My question is: why new Flutter opens two connection for a single RawSocket.connect event on a real iOS device? How can I ensure in my client code, that only one single connection will be opened (due to restrictions of the Onkyo server firmware)? |
Hi @aam, |
Based on the symptoms this is most likely related to #41451 and associated fix d7483c3, which changed socket code to try concurrent connection over IPv4 and IPv6 and choosing whatever succeeds to work-around some IPv6 connectivity issues. Though it is pretty bizarre that this would cause any sort of issues when connecting with IP addresses rather than hostnames. Could you try to change your code to pass /cc @brianquinlan |
Sorry @mkulesh , didn't get a change to run a repro yet, but @mraleph hypothesis sounds right. It seems that concurrent lookup of ipv4/ipv6 addresses affected several folks: #48652, #46102. |
Thank you for the proposal to pass If you want please feel free to close the issue. |
Many thanks for these helpful information. I've spent a lot of time to solve this problem. I store the hostIP as a String in my app settings. To connect the socket i used:
This results in a similar behavior like in @mkulesh problem. The socket opens two times. The first connection will be promptly closed and the second one alive. The server tries to answer to the first connection and the error occurs. But it's only in the iOS version and only at real devices not in the simulator environment. To cast the String as
|
I think that this should have been fixed in d884d1a (so any Dart version >= 3 should include it). With that change, Please reopen if I missed something. |
I develop a Flutter app that is a remote controller for Onkyo/Pioneer network players and AV receivers. The app communicates with players via TCP using so called "Integra Serial Communication Protocol". For the communication with the receiver, I use Socket and RawSocket classes.
After upgrading Flutter from the version 1.22.6 (Dart version 2.10.5) to Flutter version 2.0.0 (Dart version 2.12.0), I observe a critical regression in the RawSocket class. This, however, only happens on a real iOS device (iPad 7 gen in my case) and only if the app connects to a real Onkyo/Pioneer hardware. The observed behavior is that using Dart 2.12.0 and later, the RawSocket suddenly generates RawSocketEvent.readClosed after reception some portion of data immediately after a successful connection is established.
It does not happen on Dart 2.10.5 and earlier. It does not happen on iOS simulator, macOS, Android, Linux or Windows. It only happens on physical iPad (iOS 14.x and 15.1) with Dart 2.12.0 and later.
This is an example om my MessageChannel class that communicates with the remote device:
The problem is that RawSocketEvent.readClosed event is called unexpectedly with the Flutter version 2.0.0 and later, but never called with Flutter 1.22.6 and earlier.
My Flutter 2.0.0 environment:
If I open and close the app on iPad several times, the typical log output is follows:
Please note that "RawSocketEvent.readClosed" is logged that indicates RawSocketEvent.readClosed event is received.
The same code running on the same iPad with the same external receiver, but with Flutter 1.22.6
generates following output:
Please note that RawSocketEvent.readClosed is never called here.
Steps to reproduce:
main.dart.zip
expected behavior: app is opened, no log RawSocketEvent.readClosed appears
observed behavior: log RawSocketEvent.readClosed appears, connection to receiver is closed
The text was updated successfully, but these errors were encountered: