Italian Chiarimenti per traffico rete...

stefanoxjx

Active Member
Licensed User
Ciao ragazzi,
sto cercando di capire come gestire il traffico rete, però ci sono delle cose che non mi tornano e non capisco.
Vorrei quindi chiedere il vostro aiuto, perchè altrimenti mi ci vogliono 3 mesi per venirne fuori.

Ho scritto un po' di righe di codice:
B4X:
Sub Process_Globals
   Dim Client As Socket
End Sub

Sub Globals
   Dim Vibrate As PhoneVibrate 
   Dim Const IP As String = "192.168.0.252"
   Dim Const Port As Int = 80
   Client.Initialize("Client")
   Dim Astreams As AsyncStreams
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("ProvaRete")
   TitleIconView.Bitmap=LoadBitmap(File.DirAssets, "icon.png")
End Sub

Sub btnInvia_Down
   Dim command As String
   Vibrate.Vibrate(100)

   command="INVIO DATI "

   Client.Connect(IP,Port,5000)
   SendData(command)
End Sub

Sub Client_Connected (Successful As Boolean)
   If Successful = False Then
      Msgbox(LastException.Message, "Errore di connessione")
      Return
   End If

   ToastMessageShow("Connesso",False)
   Astreams.Initialize(Client.InputStream, Client.OutputStream, "AStreams")
End Sub

Sub AStreams_Error
    ToastMessageShow("Errore", True)
End Sub

Sub SendData(text As String)
   Dim buffer() As Byte
   buffer = text.GetBytes("utf-8")
   Astreams.Write(buffer)
End Sub

Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length,"utf-8")
    ToastMessageShow(msg, False)
End Sub
Allora, questo codice funziona ma con qualche problemino, e cioè:
Quando clicco su "INVIA", mi da il messaggio "CONNESSO", però non invia i dati.
Per inviare i dati devo cliccare ancora su "INVIA" e allora esegue l'invio e la ricezione dei dati.
Se dopo tutta la procedura clicco una terza volta per ripeterla mi da l'errore "already connected".
Per risolvere il problema della connessione e invio diretto dei dati (anzichè dover cliccare 2 volte sul pulsante invia) ho spostato l'istruzione SendData all'interno della sub Client_Connected, però non so
se è corretto farlo e comunque non capisco perchè devo cliccare una prima volta per connettere e una
seconda per inviare visto che l'istruzione SendData è subito dopo l'istruzione Client.Connect.
Per evitare di vedere l'errore "already connected" ho messo all'interno della funzione SendData (alla fine) l'istruzione Client.close.
Questo comporta però che se clicco nuovamente su invia mi restituisce l'errore "null.pointer".
Insomma, un po' di cosette da capire :)
C'è qualche buon'anima che può chiarirmi un po' le idee?
Grazie.
Ciao.
 

coslad

Well-Known Member
Licensed User
l' errore che commetti è proprio nel inviare i dati immediatamente dopo il comando di connessione, dagli il tempo di connettersi !!! Attendi l'evento connected e dopo invii i dati, provare per credere
 

stefanoxjx

Active Member
Licensed User
Purtroppo non è così :(
Ho già provato a mettere un delay di 3 secondi tra connect e senddata, ma non cambia nulla.
Eppure sul server la connessione che si attiva la vedo praticamente all'istante appena clicco sul pulsante.
 

stefanoxjx

Active Member
Licensed User
Ho provato anche il codice che si trova a questo link: http://www.b4x.com/android/forum/threads/auf-windows-telnet-server-verbinden.44314/#post-271064 e che è praticamente uguale a quello che ho scritto io:
Cliccando prima button1 e poi button2 funziona perfettamente, ma se sposto subito sotto Client.connect le due istruzioni che ci sono su button2 (senden("user") senden("pwd")) la connessione avviene ma dall'altra parte non arriva nessun dato.
Ultima prova, ho aggiunto un delay di 3 secondi tra connnect e queste istruzioni, ma ancora non arriva nessun dato.
Non riesco a capire :(

B4X:
Sub Button1_Click
Client.Connect("192.168.0.252",80,2000)
   Delay(3000)
     
  senden("user")
  senden("pw")
   
   
End Sub
 

LucaMs

Expert
Licensed User
Ho già provato a mettere un delay di 3 secondi tra connect e senddata, ma non cambia nulla.
@coslad non intendeva dire di usare un ritardo, ma di attendere che la connessione sia attiva, verificando questo nella routine dell'evento Client_Connected.
In quella routine, ad esempio, abiliti il tasto per inviare i dati, fino a quel momento disabilitato.

Quindi avrai due tasti: "Connetti" e "Invia"
 

stefanoxjx

Active Member
Licensed User
Infatti, come avevo scritto all'inizio, se sposto l'istruzione send all'interno della sub client_connected funziona, ma non ne capisco la logica.
Perchè spostando il send all'interno di client connected si connette e invia i dati in mezzo secondo e se invece prima faccio la connessione, poi
aspetto 3 secondi e invio i dati non funziona?
Non riesco a capire la logica di questo "funzionamento".
 

udg

Expert
Licensed User
Credo che la logica risieda nel fatto che nel primo caso (client_connected = true) l'oggetto socket setti internamente qualcosa per segnalare che il canale di trasmissione è aperto e funzionante, mentre nel secondo caso, malgrado l'attesa di 3 secondi, tale circostanza non risulti ancora occorsa.
Comprendo la perplessità implicita nel dire "ma io attendo enne secondi prima di inviare dati e quindi mi aspetto che per quel momento sia tutto ok", ma se l'oggetto funziona in altro modo perché non adeguarsi?
Per di più, nel primo post si vede che Astream viene inizializzato nel client_connected (indipendentemente dall'esito della connessione) ma utilizzato comunque in SendData.
Quindi anche il delay di 3 sec tra connessione e sendata non risolveva l'assenza di una corretta inizializzazione di astream nel senso che poteva capitare che senddata veniva eseguito prima di client_connected (vero o falso che fosse) e quindi rima di aver inizializzato Astream.

udg
 

stefanoxjx

Active Member
Licensed User
Comprendo la perplessità implicita nel dire "ma io attendo enne secondi prima di inviare dati e quindi mi aspetto che per quel momento sia tutto ok", ma se l'oggetto funziona in altro modo perché non adeguarsi?
Ciao UDG,
non è un problema di adeguarsi o meno, io mi adeguo ma devo capire come devo farlo.
Probabilmente sto ragionando con degli schemi mentali sbagliati dati da altre esperienze con altri linguaggi e sistemi.
Sto quindi cercando di capire la logica di questo sistema appunto per adeguarmi, ma finchè non vedo qualcosa che funziona
non riesco a capirne la logica.
Avrei necessità di un sistema che quando clicco (o faccio tap) sul pulsante, mi apra una connessione, mi invii un pacchetto, aspetti un eventuale conferma (che ancora non ho implementato) e chiuda la connessione.
Mi piacerebbe che tutta la procedura:
B4X:
Client.connect...
SendData...
Client.close
fosse allinterno della sub Button_click e non sparsa nelle varie funzioni client_connected ecc.
Per ovviare a questo ho provato ad usare "Client.connected" che dovrebbe appunto dirmi quando la connessione è pronta a spedire/ricevere dati, ma sembra non funzionare (almeno nel contesto in cui l'ho provata).
Inoltre, Client.close, oltre a chiudere la connessione distrugge anche l'oggetto Client e quindi alla successiva connessione devo andarlo a reinizializzare (Client.Initialize) con ulteriore codice "inutile".
Non esiste un sistema per chiudere semplicemente la connessione senza andare a deinizializzare il socket?

In tutto questo c'è sicuramente una logica che però non riesco a capire :(
 

udg

Expert
Licensed User
Potrei sbagliare, ma secondo me la tua difficoltà è più legata al doverti adattare ad un modello asincrono (piuttosto che quello sincrono che preferiresti) che agli oggetti in sé. Considera che Android è un sistema "poco paziente" e quindi è incline a terminare un'app che blocca il suo main thread troppo a lungo (se non erro 5 sec max).
Di conseguenza un po' tutte le soluzioni proposte tendono ad allegerire il main (vedi service, thread multipli ed appunto funzioni asincrone).

Anch'io troverei più semplice ed ordinato un bel blocco "apro-trasmetto/ricevo-chiudo", meglio ancora se incluso in un evento click di un tasto o qualcosa di equivalente, ma come detto dobbiamo adattarci sia al concetto di event-driven che a quello di operazioni asincrone.

Prima di riprovare con altro codice, dai un'occhiata al tutorial di Erel sul Asynstreams che espone i concetti di cui sopra in modo abbastanza chiaro e completo.

Un'ultima nota: client.initialize non metterlo in Globals ma piuttosto in Activity_Create.
 

stefanoxjx

Active Member
Licensed User
Potrei sbagliare, ma secondo me la tua difficoltà è più legata al doverti adattare ad un modello asincrono (piuttosto che quello sincrono che preferiresti)
Hai fatto centro :)
Effettivamente, io sono un programmatore molto old style e diciamo che ho abbandonato la programmazione su pc proprio quando è subentrato il mondo windows & co.
Quindi, sono rimasto con una mentalità di programmazione lineare.
Infatti mi sono accorto anch'io che sto sbattendo la testa contro questo muro e di conseguenza nasce anche la difficoltà di capire bene alcuni concetti.
 

udg

Expert
Licensed User
Eheh.. noi ex-teen ager ne abbiamo viste di cose! :D
Ma non preoccuparti, qui sei in buona compagnia..
 

udg

Expert
Licensed User
'Azz se svegliato er nonnetto!

Mo' ce tocca la solfa di quando in bicicletta annava ("che era ancora buio e faceva un gran freddo") al centro di calcolo dove lui ed altri 20 o 30 pionieri programmavano per giorni 'na bestia grande quanno l'intero piano solo per ottenere 'na stampata tipo "Aoh ce so' pur'io!".
 
Last edited:

LucaMs

Expert
Licensed User
'Azz se svegliato er nonnetto!

Mo' ce tocca la solfa di quando in bicicletta annava ("che era ancora buio e faceva un gran freddo") al centro di calcolo dove lui ed altri 20 o 30 pionieri programmavano per giorni 'na bestia grande quanno l'intero piano solo per ottenere 'na stampata tipo "Aoh ce so' pur'io!".
Programmavano? C'avevamo solo er pallottoliere! :D
 
  • Like
Reactions: udg

stefanoxjx

Active Member
Licensed User
Effettivamente credo che se avessi avuto 20 anni avrei avuto la voglia e anche il tempo di studiarmi java.
Invece con tutti gli impegni e il poco tempo (non parliamo dell'età) ho cercato qualcosa di più semplice e rapido per sviluppare.
A vent'anni non l'avrei mai fatto. Sarebbe stato uno schiaffo al mio ego :D
Quindi torniamo al discorso dell'adattarsi.
Mi sto rendendo conto che pur di riuscire a fare qualcosa mi sto adattando a molte cose che una volta non avrei preso in considerazione.
 

LucaMs

Expert
Licensed User
Ad una cosa è difficile adattarsi: all'età che avanza :( :)

Se è vero, come è vero, che un giovane impari più in fretta, d'altra parte di solito non ha le basi per capire a fondo e, soprattutto, essendo giovane fa le cose in fretta.

Alla fine penso che, dopo un po' d'esperienza fatta con B4a, tramite la quale si imparano comunque i meccanismi di Android, PERFINO alla nostra quasi giovane età potremmo imparare Java.

Non è che Java sia tutta questa complicazione; l'importante è conoscere almeno un po' la programmazione ad oggetti.

Io non ho avuto la pazienza di imparare bene l'ambiente Eclipse, come importare progetti e librerie e, soprattutto, come capire gli errori; fatto questo, studiando il codice scritto da altri, si capirebbe già molto.

Ma finché non si hanno problemi con B4A, vale la pena farlo?

Io avevo iniziato, ma una volta scoperto B4A ho pensato, e credo di non aver sbagliato, di abbandonare Android+Java+Eclipse.


[dimenticavo (stranamente, hehehe) che anche molti diversamente giovane sicuramente usano Java. Il difetto sta nel... sognare di guadagnare con le app, cosa che secondo me è quasi come sperare di vincere al Superenalotto]
 
Top