2013-10-28 13 views
7

Sto lavorando a un'applicazione Android che invia/riceve un volume elevato di traffico UDP a un endpoint Windows su una WLAN (e no, non posso usare TCP).Ritardo UDP/lag enorme con Android

Il problema è che quando accelero il traffico, comincio a vedere ENORME ritardi tra quando chiamo sendto (l'app è scritta con l'NDK) e quando vedo il pacchetto arrivare all'endpoint di Windows. Nelle vicinanze di 10 secondi! La stessa cosa accade anche al contrario: vedo ritardi enormi tra il pacchetto inviato dall'endpoint di Windows e rilevato da recvfrom().

  • La modifica di SO_SNDBUF non ha alcun effetto, quindi non penso che sia un problema con il controllo del buffering a livello di applicazione.
  • Ho verificato che il problema esiste su una varietà di dispositivi Android, quindi non credo che sia un problema con l'hardware/driver wireless
  • con uno sniffer e correlare i timestamp, mi ha confermato che il ritardo è che si verificano tra chiamare sendto() e il pacchetto viene inviato dal dispositivo Android, in modo che il buffer non sta accadendo nel AP o endpoint di Windows

quindi a questo punto io sono tutto, ma a corto di idee. I fatti mi porterebbero a credere che il buffering stia accadendo sul livello del SO Android, ma 10 secondi di traffico a 10 Mbps? Sembra troppo alto per essere fattibile per un sistema operativo in cui l'impronta della memoria è una preoccupazione così grande.

Inoltre, se il problema è che sto invio di dati troppo veloce e travolgente il sistema operativo, quindi mi aspetterei sendto() per restituire ENOMEM o ENOBUFS ... Ma non ci sono indicazioni che qualcosa è sbagliato su Android livello di applicazione.

Quindi la mia domanda è: cosa sta causando questo ritardo? E c'è un modo per mitigarlo, o devo modificare la mia applicazione per avere timeout più lunghi o qualche modo per scoprire questa condizione prima che diventi cattiva?

+0

Forse la tua CPU è troppo occupata? –

+0

@AlexCohn Ho appena controllato con un'app di monitoraggio della CPU; è occupato ma non troppo occupato (massimo del 20% circa) –

+0

http://developer.android.com/reference/android/os/Debug.html#startMethodTracing() http://developer.android.com/tools/ debugging/ddms.html # network – auselen

risposta

3

Stai inviando troppo .. quanto stai inviando? 10 Mbps è decisamente troppo alto. Tenete a mente:

  1. Ogni datagram UDP inviare ha un ulteriore 28 byte di intestazione (UDP + IP su IPv4)
  2. velocità di collegamento di collegamento sono limiti massimi teorici che non si sarà mai in grado di raggiungere
  3. Il Il sistema operativo del telefono potrebbe limitarti, il sistema operativo del telefono deve conservare la batteria e cercare di ridurre al minimo le comunicazioni da parte del socket.

O

Tu dici la tua CPU è al 20%, il numero di core Possiedi - si potrebbe essere maxing il nucleo che sta facendo l'invio, vale a dire la velocità di elaborazione è il collo di bottiglia.

+0

Capisco che sto mandando troppo. Il mio obiettivo è quello di spingere i limiti del dispositivo; è intenzionale e mi aspetto che fallisca. È solo, mi aspetto che non riesca restituendo un errore, non tamponando 10 MB di dati! –

+0

Vedo, bene come osservato può bufferizzare il 10 MB, non mi sorprende – markmnl

0

Ho visto rapporti di comportamento molto simile nella lista linux-rt ultimamente, che possono essere correlati.

http://comments.gmane.org/gmane.linux.rt.user/10163

Per un diversi mesi stavo infestata con jitter spuria, rilevati su

messaggi UDP - messaggi UDP multicast dove hanno ricevuto il origine nodo senza alcun ritardo, ma su altri nodi è stato rilevato un ritardo nell'intervallo di 10 secondi di millisecondi. Semplicemente, sembrava che un messaggio fosse bloccato nel kernel prima di essere finalmente trasmesso. Infine, grazie allo strumento LTTng, sono stato in grado di individuare il problema a questa pace di codice in net/sched/sch_generic.c:

Ci sembra essere un problema di blocco sulla trasmissione che causa lo stallo del tx.

1

Per le persone con lo stesso problema:

Prova riutilizzare la DatagramSocket. Questo l'ha risolto per me.

+0

Grazie; Ci proverò qualche volta –