Schwere UDP-Paketverlust auf einigen Android-Geräten

Ich habe das Interwebz ohne Ergebnis geputzt. Wir stehen vor einem Problem, bei dem einige Android-Geräte einen schweren Paketverlust erleben. Um etwas Hintergrund zu geben, verbindet sich die Anwendung mit einem bestimmten Wifi und sucht nach UDP-Paketen, die auf Port 17216 gesendet werden. Diese Pakete sind von Größe 832 Bytes, mit Ausnahme der eingewickelten Header und werden mit einer regulären Rate von vier pro Sekunde gesendet.

Wir haben das Problem nur auf zwei Geräten, einem Low-End-Turbox Rubik II-Tablet und einem ASUS Memo Pad HD 7 getroffen. Die anderen Geräte, die wir getestet haben (Telefone und Tablets), sammeln die Pakete im regulären Intervall.

  • Wie drückst du die Taste in android programmgesteuert zurück?
  • Halten Sie libgdx Kamera innerhalb Grenzen beim Schwenken und Zoomen
  • Lesen und Schreiben von Integer-Array zu Paket
  • Wie man App-Anfragen an Freunde über Facebook Android SDK zu senden
  • Wie bekomme ich Android Studio?
  • Android Content Provider Liste
  • Die Funktion, die die Pakete empfängt, ist:

    public void run() { while (isUDPServerRunning) { try { socket.receive(packet); ProcessRawPacketData(); DisplayLoggingInfo(); } catch (IOException e) { Log.e("receive", e.getMessage()); e.printStackTrace(); } } } 

    Und das ist Teil eines Runnable . Die Steckdose wird so erstellt:

     byte[] buffer = new byte[1024]; DatagramSocket socket; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 

    onCreate() die Steckdose in der onCreate() Methode unserer Service initialisiert wird:

     socket = new DatagramSocket(SERVERPORT); 

    Die Pakete werden vom Wifi-Modul empfangen. Wir haben bestätigt, dass durch das Wurzeln eines der Geräte und die Installation eines Paket-Sniffer, so dass das Problem irgendwie Code verwandt sein muss.

    Auf den betroffenen Geräten werden Pakete für ein paar Sekunden korrekt empfangen und dann gibt es einen vollständigen Ausfall, der für einige Sekunden dauert, also schätze ich, dass der Verlust 50% übersteigt.

    Jede Hilfe wäre sehr geschätzt. Wir ziehen unsere Haare aus.

    Update Ich habe mich über den Paket-Sniffer verwechselt. Es scheint, dass der Paket-Sniffer auch mehrere relevante Pakete auf dem verwurzelten Gerät verliert. Manchmal , aber, einfach das Starten des Paket-Sniffer behebt das Problem! Wenn man Bluetooth ein- oder ausschaltet, wie unten vorgeschlagen, scheint es keinen Unterschied zu machen. Könnte dies ein anderes Hardware-Problem sein?

    Update 2 Hier ist ein Beispiel für die Protokolle, die ich sofort nach der socket.receive() Zeile socket.receive() . Beachten Sie, wie es eine halbe Minute Pakete überspringt und dann für ein paar Sekunden gut funktioniert.

     05-25 15:44:38.670: D/LOG(4393): Packet Received 05-25 15:44:38.941: D/LOG(4393): Packet Received 05-25 15:45:09.482: D/LOG(4393): Packet Received 05-25 15:45:09.716: D/LOG(4393): Packet Received 05-25 15:45:09.928: D/LOG(4393): Packet Received 05-25 15:45:10.184: D/LOG(4393): Packet Received 05-25 15:45:10.451: D/LOG(4393): Packet Received 05-25 15:45:10.661: D/LOG(4393): Packet Received 

  • Video nicht korrekt mit Listenansicht in android spielen
  • Wie kann ich Android / data / your.package.name-Dateien auf dem externen Speicher in Android 4.2 mit der Multi-User-Umgebung anzeigen?
  • Retrofit 2.0b2: Wie bekomme ich InputStream aus der Antwort?
  • Benutzerdefinierte Benachrichtigung: java.lang.RuntimeException: schlechte Array-Längen
  • Wie bekomme ich Webview Skala in Android 4
  • Wie zentriert man das Layout im Android Dialog?
  • 4 Solutions collect form web for “Schwere UDP-Paketverlust auf einigen Android-Geräten”

    Paketverlust (wie Sie wissen, natürlich) kann auf mehreren Stufen entlang der Übertragung passieren:

    1. Senden vom Server
    2. Übertragung über das Netzwerk
    3. Physischer Empfang beim Kunden und Handling in Hardware
    4. Verarbeitung / Pufferung des Pakets im Kernel / OS
    5. Handhabung / Pufferung des Pakets in Ihrer App.

    Sie können schnell überprüfen, ob Punkt 1 oder 2 ein Problem sind, indem andere Geräte auf dieselbe Sendung hören, während sie mit demselben Wifi-Router verbunden sind. Klingt wie du das schon gemacht hast und dass es kein Problem gibt. (Beachten Sie, dass ein Paket, das in Schritt 2 (oder manchmal sogar 1) gelöscht wird, möglicherweise nicht aus dem WireShark-Dump fehlt, wenn Sie es auf dem Server ausführen.)

    Punkte 3 bis 5 sind daher wahrscheinlich das Problem und sie könnten ein wenig schwerer zu trennen sein.

    Hier sind ein paar Dinge, die helfen könnten:

    • Wie @Mick vorgeschlagen, nicht nur ausdrucken, wenn Sie das Paket erhalten, aber geben Sie jedem Paket eine zunehmende ID-Nummer, um herauszufinden, ob Sie tatsächlich ein Paket verloren oder ob es nur verzögert wurde.
    • Verschieben Sie Ihren paket-empfangenden Code in seinen eigenen Thread (falls nicht bereits) und legen Sie die Priorität dieses Threads auf MAX_PRIORITY, um die Chance zu minimieren, dass Ihr Code die Lunch-Zeile hält. Angesichts der Tatsache, dass die Memo Pad ist ein Quad-Core-1,2 GHz-Maschine, MAX_PRIORITY sollte nicht einmal notwendig sein, aber wenn Sie derzeit nicht die Empfangsschleife in seinem eigenen dedizierten Thread, können Sie sehen, Hick-ups sowieso. Wenn das die Dinge behebt, hab einfach eine minimale Empfangsschleife die Pakete in deine eigene Puffer-Warteschlange und habe einen unabhängigen Thread-Prozess.
    • Überprüfen / erhöhen Sie die Größe des Paketpuffers für den Empfang von Paketen über setReceiveBufferSize (…) ( ausführlicher Java-Referenz hier ). Stellen Sie sicher, dass Sie eine Größe angeben, die viele Pakete enthalten kann. Angesichts der Tatsache, dass das Laufen der Paket-Sniffer manchmal scheint, um Dinge zu helfen, es klingt wie es könnte einige Socket-Einstellung, die Dinge verbessern kann, die der Sniffer passiert zu setzen.
    • Auf dem Server können Sie auch ein Tag zum Paket hinzufügen, das allen beteiligten Geräten mitteilt, wie das Paket behandelt werden soll. Wenn Sie setTrafficClass (IPTOS_RELIABILITY) anrufen , bitten Sie alle Beteiligten, ihre Pakethandhabung für maximale Zuverlässigkeit zu optimieren. Nicht alle Geräte werden kümmern, aber es kann einen Unterschied machen.
    • Sie können versuchen, DatagramChannels anstelle von DatagramSockets zu verwenden und dann select () zu verwenden, um zu warten, bis das nächste Paket gelesen wird. Während dies technisch sollte nicht einen Unterschied machen, manchmal mit einem anderen API-Aufruf kann eine Arbeit für ein Problem bieten.
    • Leider ist Android ein sehr heterogenes Umfeld, in dem viele Hersteller ihre eigenen Kernelmodule, etc. anbieten. Dies führt auch verschiedene Inkompatibilitäten oder Nicht-Standard-Verhalten überall. Sie könnten in der Lage sein, eine benutzerdefinierte ROM (Cyanogen, etc.?) Für eine oder beide Ihrer Problem-Geräte zu finden. Bei der Installation, dass anstelle der Fabrik ROM Ihr Problem behebt, dann ist es ein Bug in den Hersteller zur Verfügung gestellt (Kernel) Netzwerk-Treiber, in welchem ​​Fall könnten Sie Glück haben, um eine Arbeit zu finden, oder Sie könnten vielleicht einen Bug-Report Datei Mit ihnen, aber im Allgemeinen können Sie nur diese Geräte als nicht unterstützt im Play Store auswählen, um schlechte Bewertungen zu vermeiden …

    Schließlich ist hier ein Work-around, das das Problem sicher beheben sollte:

    Fügen Sie Ihrem Client einen Code hinzu, der gelöschte Pakete erkennt und wenn die Drop-Rate zu hoch ist, öffnet sich stattdessen eine TCP-Verbindung zum Server, die dann die Paketlieferung garantiert. Angesichts der Tatsache, dass Ihre Pakete klein und selten sind und dass nur ein paar Geräte jemals brauchen, um diesen Mechanismus zu verwenden, glaube ich nicht, dass dies ein Problem für Ihre Server-Last verursachen sollte. Wenn Sie keine Möglichkeit haben, den Server-Code zu ändern, um einen TCP-Stream bereitzustellen, können Sie einen unabhängigen Proxy-Server schreiben, der die UDP-Pakete sammelt und über TCP verfügbar macht. Wenn Sie es auf demselben Rechner wie der ursprüngliche Server ausführen können, wissen Sie sogar, welche IP-Adresse es ist (genauso wie die Quelladresse der UDP-Pakete, die angekommen sind).

    Nur eine wilde Vermutung, aber wie lange nehmen deine Berechnungen auf dem Paket? Ist es möglich, dass der zugeordnete Puffer für die Steckdose füllt und beginnt, die Pakete zu fallen?

    Ich weiß, das klingt unwahrscheinlich für eine Übertragungsrate bei ca. 4 KB / s … Aber wenn Ihre Berechnungen länger als 250 ms dauern, als dies früher oder später auftreten würde. Dies würde auch erklären, warum einige Geräte wie ein Charme arbeiten, und andere nicht.

    Haben Sie versucht, die Berechnungen zu entfernen und nur die "Paket empfangen" Nachricht zum Debuggen zu drucken?

    Interessanterweise passieren beide Geräte, die UDP-Paketverlust erleben, Mediatek SoCs. Haben deine anderen Testgeräte den gleichen Chipsatz?

    Dies kann ein Fehler im Fahrer für die Wi-Fi dieser SoCs sein. Sein, dass es nur mit UDP auftaucht und nicht immer 100% ist, kann es bis jetzt unbemerkt von allen bisher gewesen sein.

    Dies klingt sehr ähnlich wie Bluetooth-Interferenz-Symptome, die auf Android (und iOS – in der Tat alles mit WiFi und Bluetooth zusammen) Geräte gesehen werden können.

    2.4Ghz WiFi und Bluetooth teilen sich die gleiche Bandbreite und können sich gegenseitig stören – bei manchen Geräten ist dies ausgesprochen, vielleicht aufgrund des internen Layouts.

    Es ist auch möglich, dass man es auf einigen Geräten und nicht anderen sehen kann, weil die Versionen von WiFi sie unterstützen – das neuere 5GHz basierte Wifi nicht mit bluetooth in der gleichen Weise stören, aber einige ältere oder mehr grundlegende Android-Geräte nicht unterstützen können Dies.

    Sie können testen, ob dies die Ursache ganz einfach ist, indem Sie bluetooth auf dem Gerät während des Testens ausschalten (wenn Ihre App ohne Bluetooth funktionieren kann).

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.