Italian UDP_PacketArrived Dati ricevuti ?

Xfood

Expert
Licensed User
Buongiorno a tutti,
sto impazzendo ancora con la gestione udp,
cioe' mi arrivano i dati correttamente, ma non so quando ho finito di ricevere tutti i dati,
come si fa a sapere si i dati sono arrivati tutti?
mi spiego, invio una stringa tramite udp, e poi il device mi risponde con un'altra stringa di lunghezzza variabile a cui non so mai quale sia la lunghezza,
per cui arrivano i dati tramite UDP_PacketArrived a Pacchetti,
io dovrei elaborare la stringa solo dopo averla ricevuta tutta, ma non so mai quando ha finito di ricevere tutta la stringa.
Ecco il codice che utilizzo

B4X:
Sub Process_Globals
    Dim UDPSocket1 As UDPSocket
End Sub

Sub Globals
    Private LETTURA As String
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("vmain")
    Activity.Title = "UDP"
    LETTURA=""
    UDPSocket1.Initialize("UDP", 9000, 1024)
    UDP_Send(UDPSocket1, "testo", 192.168.1.10, 9000)
    ' qui dovrei elaborare i dati ricevuti e contenuti nella variavbile lettura
    ' ma trovo solo gli ultimi byte, come facci a sapere quando ha finito di ricevere i dati
    ' la sub UDP_PacketArrived (Packet As UDPPacket)'
    log(LETTURA.Length)
End Sub

Sub UDP_PacketArrived (Packet As UDPPacket)
    Dim msg As String = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "UTF8")
    LETTURA=LETTURA & msg
End Sub

Sub UDP_Send(socketa As UDPSocket, command As String, ipaddress As String, port As String)
    Dim Packet As UDPPacket
    Dim data() As Byte
    data = command.GetBytes("UTF8")
    Dim myIp As String =UDPSocket1.GetBroadcastAddress
    
    Packet.Initialize(data, myIp, port)
    socketa.Send(Packet)
End Sub

l'unico modo che ho trovato e' mettere un timeout fisso, ma cosi devo aspettare la fine del timeout , anche se i dati sono arrivati prima,
oppure se la stringa e' molto lunga devo prevedere un timeout piu lungo,
non esiste un metodo per verificare lo stato di UDP_PacketArrived, se ho finito, ritorno una variabile true?

ecco il metodo che ho utilizzato ma che non mi sembra professionale:

B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("vmain")
    Activity.Title = "UDP"
    LETTURA=""
    UDPSocket1.Initialize("UDP", 9000, 1024)
    UDP_Send(UDPSocket1, "testo", 192.168.1.10, 9000)
    Wait For (Attesa(1000)) Complete (Success As Boolean)
   log(LETTURA.Length)
  
End Sub

Sub Attesa (Timeout As Int) As ResumableSub
    Do While Timeout > 0
        Sleep(100)
        Timeout = Timeout - 100
    Loop
    Return True
End Sub
 

OliverA

Expert
Licensed User
Longtime User

OliverA

Expert
Licensed User
Longtime User
Anche se i pacchetti UDP possono avere dimensioni fino a 64 KB, se lo sviluppatore del dispositivo, la libreria sottostante utilizzata dallo sviluppatore o il sistema operativo del dispositivo decide di tagliare la stringa durante l'invio, non è possibile UDP stesso per sapere quale pacchetto contiene l'ultima parte della stringa.

Using Google Translate. Original text:
Even though UDP packets can be up to 64KB in size, if the developer of the device, the underlying library that the developer uses, or the operating system of the device decides to chop up the string while sending it, then there is no way for UDP itself to know which packet contains the last portion of the string.
 

Xfood

Expert
Licensed User
Ok, quindi l'unico modo e' utilizzare un timeout di attesa. Grazie
 

OliverA

Expert
Licensed User
Longtime User
Forse. Hai guardato gli ultimi due byte della stringa che hai completato la stringa che ricevi? Se l'ultimo byte della stringa ha un valore pari a 10 o gli ultimi due byte sono un 13 seguito da un 10, è possibile utilizzare AsyncStreamsText per gestire il riassemblaggio della stringa senza richiedere un periodo di timeout.

Maybe. Have you looked at the last two bytes of the string that you completed string that you receive? If the last byte of the string has a value of 10 or the last two bytes are a 13 followed by a 10, then you can use AsyncStreamsText to handle re-assembling your string without requiring a timeout period.
 

udg

Expert
Licensed User
Longtime User
Magari il carattere di fine pacchetto è un altro. Non è detto che sia CR/LF.
Oppure è possibile che all'inizio del pacchetto sia indicata la sua lunghezza.
Prova a confrontare due o tre pacchetti ricevuti (o anche a pubblicarli qui se non contengono dati riservati).
 

Xfood

Expert
Licensed User
Lunedi allego i pacchetti che arrivano, grazie x il tuo interessamente.
 

Xfood

Expert
Licensed User
Buongiorno,
il codice udp che riceve i dati e' cosi:
B4X:
' a packet of data has arrived
Sub UDP_PacketArrived (Packet As UDPPacket)
    Dim msg As String = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "UTF8")
    LETTURA=LETTURA & msg
    If Len(txtResponse.Text) = 0 Then
        txtResponse.Text = msg
    Else
        txtResponse.Text = txtResponse.Text &  msg  '";" & msg
    End If

    StateManager.setSetting("response", txtResponse.Text)
    StateManager.SaveSettings
    TextWriter1.WriteLine(msg)
    
End Sub

se il server in ascolto non e' raggiungibile la risposta e' uguale alla richiesta cioe 80177609 file allegato Text_server non risponte.txt

server attivo, interrogo un articolo in promo ecco la risposta: file Text_rispostaOk.txt
80177609
B0
.:
KINDER CIOCC


.3
per Clienti Fidelity
Sconto 0,20 ogni Pz 1


B1
.7
Eur. 0,99


server attivo, interrogo un articolo offerta fidelity ecco la risposta: allego file Text_rispostaOk2.txt
80015598
%
B0
.:
LEVISSIMA AC


.3
per Clienti Fidelity
Sconto 0,20 ogni Pz 1


B1
.7
Eur. 0,50


server attivo, interrogo un articolo inesistente, ecco la risposta: allego file Codice_Non_trovato.txt
90177609
%
B0
Informazioni Prodotto

.4
Non Disponibili

ogni fine pacchetto trovo un carattere ETX, MA NON SO MAI SE HA FINITO COMPLETAMENTE DI TRASMETTE.....
 

Attachments

  • pacchetti.zip
    937 bytes · Views: 149

udg

Expert
Licensed User
Longtime User
Aprendo il file Text_rispostaOK.txt in esadecimale, si vede che i tre blocchi di infomazione sono chiusi dalla sequenza 030a03, ovvero ETX-LF-EXT e separati dalla sequenza LFLF
All'interno di ciascun blocco sembrano esserci dei comandi (preceduti da ESC) e delle stringhe. Tutti terminati da LF tranne l'ultima che ha la chiusura blocco
Quindi nel primo blocco hai:
38303137373630390a1b42300a1b2e3a0a4b494e4445522043494f4343030a030a0a
80177609LF
ESCB0LF
ESC.:LF
KINDER CIOCCETXLFETX
LFLF

Secondo blocco
1b2e330a70657220436c69656e746920466964656c6974790a53636f6e746f20302c3230206f676e6920507a2031030a03a0a0
ESC.3LF
per Clienti FidelityLF
Sconto 0,20 ogni Pz 1ETXLFETX
LFLF

Terzo blocco
1b42310a1b2e370a4575722e2020302c3939030a03
ESCB1LF
ESC.7LF
Eur. 0,99ETXLFETX

Quindi mi sembra che sia necessario individuare la fine di un blocco (ETX-LF-ETX) per poter estrarre delle informazioni utili dallo stesso
 

Xfood

Expert
Licensed User
Grazie @udg , il problema e che non so mai
Di quanti blocchi e' formata una risposta, per cui non so quando lanciare l'elaborazione delle stringhe/ blocchi, perche i dati sono contenuti in.tutti i blocchi, e devo aspettare di averli ricevuti tutti, per poter popolare ip display. Avevo visto che ogni blocco ha una chiusura, ma continuano ad arrivare blocchi, 1/ 3/ 4 avvolte 2, dipende dalla risposta.
So che al massimo sono 5 blocchi per ogni richiesta, per cui ho mesdo un timeout di 2 secondi per essere sicuro di aver ricevuto tutti i blocchi. Non so come fare a sapere se i blocchi sono arrivati tutti.
 

udg

Expert
Licensed User
Longtime User
Dando un'occhiata anche a Codice non trovato, mi devo correggere. La fine di un blocco sembra essere ETX-LF.
Quindi il caso precedente diventa:

Blocco 1
38303137373630390a1b42300a1b2e3a0a4b494e4445522043494f4343030a
80177609LF
ESCB0LF
ESC.:LF
KINDER CIOCCETXLF

Blocco 2
030a
ETXLF

Blocco 3
0a1b2e330a70657220436c69656e746920466964656c6974790a53636f6e746f20302c3230206f676e6920507a2031030a
LF
ESC.3LF
per Clienti FidelityLF
Sconto 0,20 ogni Pz 1ETXLF

Blocco 4
030a
ETXLF

Blocco 5
0a1b42310a1b2e370a4575722e2020302c3939030a
LF
ESCB1LF
ESC.7LF
Eur. 0,99ETXLF

Blocco 6
030a
ETXLF

Per "Codice non trovato", abbiamo:
39303137373630390a1b250a1b42300a496e666f726d617a696f6e692050726f646f74746f030a0a1b2e340a4e6f6e20446973706f6e6962696c69030a
Blocco1
39303137373630390a1b250a1b42300a496e666f726d617a696f6e692050726f646f74746f030a
90177609LF
ESC%LF
ESCB0LF
Informazioni ProdottoETXLF

Blocco2
0a1b2e340a4e6f6e20446973706f6e6962696c69030a
LF
ESC.4LF
Non DisponibiliETXLF

Quindi lo start è il codice prodotto che interroghi (seguito da LF) e lo stop è la coppia ETX-LF.
Come sapere se un codice prodotto sarà seguito da uno o più blocchi informativi ulteirori? Non saprei, a meno che i codici ESC non siano in grado di fornire un indizio.
 

ivanomonti

Expert
Licensed User
Longtime User
scusate se mi intrometto, quanto può essere lunga una stringa UDP sia in trasmissione che in recezione
 

Xfood

Expert
Licensed User
scusate se mi intrometto, quanto può essere lunga una stringa UDP sia in trasmissione che in recezione
post 4 @OliverA ha gia risposto alla tua domanda dimensioni fino a 64 KB per pacchetto inviato
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…