[Shield WiFi] La connessione TCP si interrompe dopo alcuni secondi di inattività

Dunque... intanto grazie per la risposta, vediamo se riesco ad aggiungere qualche informazione utile:
Da quel che leggo dalla documentazione di Node.js (link a fine post) i socket di default non hanno timeout e il "keep-alive" (quello originale di TCP, ovvero un pacchetto vuoto e non un'implementazione personalizzata) non è attivo.
Ho modificato il server attivando il "keep-alive" per tutti i socket in entrata e impostandogli un delay dall'ultimo pacchetto ricevuto di 100ms, ma la situazione non cambia... dopo qualche secondo dall'ultimo pacchetto ricevuto/inviato dall'Arduino mi viene comunicato tramite console: "disconnecting.".

NB: Una cosa strana che ho notato solo ora è che Arduino mi segnala la connessione come chiusa (ed effettivamente non posso più trasmettere dati in nessuna direzione), però il server non si accorge minimamente della chiusura fino al primo tentativo di scrittura/lettura.
Descrivo un attimo questa cosa per chiarire la dinamica:
Praticamente ho uno o più client connessi e il server fa un broadcast dei messaggi ricevuti su tutti i client (eccetto l'autore del messaggio)... sostanzialmente è una chat minimale che sto usando per imparare.

  • Due client si connettono. (un terminale con comando "telnet" e un Arduino)
  • I client si scambiano messaggi con una frequenza tale da mantenere in vita la connessione con l'Arduino. (fin qui tutto regolare)
  • Ad un certo punto lascio cadere volutamente la connessione di Arduino.
  • Invio un nuovo messaggio dal client "telnet".
  • Il server va in crash lamentandosi del fatto che sto cercando di scrivere su un socket ormai chiuso.

Naturalmente questo non si verifica se a disconnettersi (anche in maniera brutale) è un client diverso da Arduino perchè ho programmato il server in modo che cancelli i socket dalla lista di broadcast appena viene rilevata la chiusura.

Come test aggiuntivi posso dire che tramite comando "telnet" da una macchina remota verso il server la connessione si stabilisce senza problemi e senza interruzioni... naturalmente anche i messaggi trasmessi viaggiano senza errori. Lo stesso discorso vale anche per un piccolo client che ho scritto in Node.js giusto per avere un'ulteriore conferma: anche in questo caso la connessione viene mantenuta fino ad interruzione manuale.

Link utili:
http://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback

P.S.
Dimenticavo: non ho idea di come impostare tempi di timeout o la funzionalità keep-alive dal codice sull'Arduino, ho guardato la documentazione ma non ho trovato nulla a riguardo quindi non posso assolutamente escludere che si tratti anche di questo!

NB: Una cosa strana che ho notato solo ora è che Arduino mi segnala la connessione come chiusa (ed effettivamente non posso più trasmettere dati in nessuna direzione), però il server non si accorge minimamente della chiusura fino al primo tentativo di scrittura/lettura.

questo è normale se una delle due parti si disconnette senza inviare il debito messaggio di chiusura, nulla di preoccupante se non che arduino non si sta comportando bene, anzi...
probabilmente possiede qualche time-out interno e non riescie a gestire i keep-alive o qualcosa del genere... che chip ha la tua ethernet shield?

hai un software tipo wireshark così da analizzare il traffico TCP/UDP?

In realtà, come ho scritto nel primo post, non si tratta dell'Ethernet Shield ma del WiFi Shield ufficiale: http://arduino.cc/en/Main/ArduinoWiFiShield

Per quanto riguarda l'analisi del traffico mi informo su come si utilizza wireshark e provo a fornirti un resoconto perchè da solo probabilmente non saprei come interpretarlo... se ho capito bene devo analizzare il traffico sulla mia macchina linux (server) per capire se il comportamento anomalo può derivare dalla comunicazione client/server, altrimenti potrebbe essere semplicemente un intoppo nella libreria WiFi?

Inoltre c'è da dire che la libreria WiFi l'ho scaricata dal sito ufficiale, ma c'è scritto chiaramente che verrà inclusa nel core solo in una prossima versione dell'IDE... non vorrei che fosse ancora in fase di sviluppo!

The WiFi Library will be included in a future release of the Arduino IDE. You can download the most recent version, and install it as you would any other library.

Fonte: http://arduino.cc/en/Guide/ArduinoWiFiShield

no, è che la versione attuale semplicemente è antecedente alla wifi shield.. che però è molto nuova, quindi potrebbe avere qualche intoppo.

con wireshark iniziamo a capire dove ricercare il problema, anche se ad occhio c'è qualche timeout da parte di arduino

Allego il resoconto della sniffata fatta con wireshark, ho ristretto il campo coinvolgendo solo i risultati che includevano l'IP dell'Arduino in modo da evitare di raccogliere troppi dati inutili.

Il codice dell'Arduino è semplicemente quello che ho postato sopra con l'aggiunta di una riga di scrittura aggiuntiva usata come debug:

client.println("Hi!");

Questa riga viene eseguita appena connesso al server.

Il server invece è molto semplice ed esordisce con un messaggio di benvenuto all'inizio di ogni nuova connessione.
Praticamente all'evento di connessione eseguo:

socket.write('Welcome to the Telnet server!\n');

La "cattura" con wireshark va dal momento in cui carico lo sketch sull'Arduino fino al momento della disconnessione automatica del dispositivo... l'ultimo pacchetto registrato arriva praticamente nello stesso momento in cui mi compare la scritta "disconnecting." nella console di Arduino.

ArduinoWifi_wireshark_capture (1007 Bytes)

non posso vedere i log perchè sono a lavoro, ma un amico che li ha analizzati mi dice che dopo 12 secondi che arduino dice "hi", invia un reset della connessione. Quindi il time-out è lato arduino.

dal Reference pare non esista un metodo per settare il time-out, quindi probabilmente è hard-codato nella libreria

Infatti anche a me sembrava così, però non so esattamente cosa sia il reset... perchè se fosse la richiesta di chiusura della connessione il mio server dovrebbe accorgersene come fa per tutti gli altri client, no?

Ad ogni modo sto provando ad analizzare il sorgente della libreria, non ci sto capendo molto, ma se trovo qualcosa di sospetto lo segnalo qui! :wink:

attento, il reset di connessione non è la stessa cosa di una chiusura connessione

Nada, non sono ancora riuscito a tirarci fuori nulla... nella libreria non trovo riferimenti a questo timeout fantasma, ma probabilmente sono anche io che non la riesco a leggere completamente!

Temo di essermi arenato! :frowning:

Nessuna novità dall'analisi con wireshark? (nessuna fretta eh, è giusto per sapere se hai ancora qualche freccia al tuo arco! ;))

no, noin c'è altro da tirar fuori

Può essere il caso di segnalare questa cosa o devo adeguarmi io e rassegnarmi a mandare un pacchetto ogni tanto per risvegliare la connessione? :frowning:

P.S. Se devo segnalarlo, sapresti indicarmi il modo più adeguato?

Intanto grazie mille per tutto, sei stato gentilissimo! :wink:

non so se funziona il trucco di inviare il messaggio. Apri un ticket su github GitHub - arduino/Arduino: Arduino IDE 1.x

Certo che ti sei andato a infilare in un bel tunnel. :grin:
Leonardo: scheda nuova
WiFi Shield: ancora più nuova
Librerie Wifi: nuovissime. :sweat_smile:

In questi casi un bug può essere sempre in agguato. :blush:

una domanda arduino è open source ma anche la wi fi shield lo è?

Madwriter:
una domanda arduino è open source ma anche la wi fi shield lo è?

Credo di si, anche se al momento non hanno ancora rilasciato il sorgente del firmware.

PaoloP:
Certo che ti sei andato a infilare in un bel tunnel. :grin:
Leonardo: scheda nuova
WiFi Shield: ancora più nuova
Librerie Wifi: nuovissime. :sweat_smile:

In questi casi un bug può essere sempre in agguato. :blush:

Infatti me la sono proprio cercata! :stuck_out_tongue:
Beh, almeno sarà utile per fare un po' di debug! xD

Ciao a tutti :slight_smile:
io ho lo stesso problema credo e non riesco proprio a risolverlo utilizzo Arduino Uno R3, WiFi Shield R3, libreria presa da arduino.cc
Nella mia prova (con gli esempi presenti nella libreria wifi) Arduino mi fa da server, accetta la connessione di un client mi da "new client" quindi tutto ok e dopo pochissimi secondi mi da "client disconnected" invece con l'Ethernet Shield funziona tutto bene con la stessa tipologia di esempio. Qualcuno è riuscito a risolverlo? Ho provato con un "heartbeat" inviato ogni 5 secondi da arduino al client e la durata della connessione si è allungata ma varia da 5 minuti ad 1 ora... :~
voi come avete implementato la soluzione? mi consigliate di aspettare aggiornamenti?
Grazie mille :slight_smile:

Ciao! :slight_smile:
Posso consigliarti di aumentare la frequenza degli HB, non appesantiscono l'arduino e nemmeno il server perchè generano un traffico molto piccolo (specialmente se paragonato ad altre situazioni molto comuni come giochi online multiplayer o cose simili...). Io ho impostato un delay di 500 millisecondi e mi trovo molto bene.

Ad ogni modo dobbiamo aspettare una risposta dallo staff, se vuoi puoi unirti a me e ad altri utenti che abbiamo segnalato il problema: http://code.google.com/p/arduino/issues/detail?id=1024
Più il bug verrà confermato e più probabilità ci sono che venga preso in considerazione! :wink:

Ciao, continuo a fare dei test aumentando la frequenza degli HB grazie per il consiglio :slight_smile:
Intanto ho segnalato anche io il problema nel link che hai scritto, speriamo venga risolto presto :slight_smile: