Il giorno 15/lug/2011, alle ore 08.37, Simone Ziraldo ha scritto: >> il fatto che sia wi-fi è un dettaglio implementativo, fosse via cavetto >> ethernet il discorso sarebbe esattamente lo stesso >> (scusa è che se no sembra che le socket abbiano a che fare esclusivamente >> con le connessioni wi-fi quando invece sono un astrazione moolto più >> generale generale) > si si, era solo per fare un esempio pratico di come ottengo il problema. > >> venendo al tuo problema: non mi risulta che sia possibile, per risolvere un >> problema simile costringevo il client a mandarmi un pachetto di acknowledge >> entro tot secondi >> >> in pratica il ruolo di tale pacchetto era esclusivamente quello di segnalare >> "sono ancora vivo" >> >> se il server non riceveva dati o acknowledge entro tot tempo assumeva che il >> client fosse morto e chiudeva la socket > ci avevo pensato ma il problema è che il server rimane fermo su s.recv quando > cade la connessione e quindi non posso fare altre comunicazioni... > > Le soluzioni che mi vengono in mente in questo momento sono due: > 1) fare un socket.accept prima di ogni socket.recv, in questo modo avrei > maggiore probabilità di avere una connessione funzionante per il recv > 2) mandare il comando socket.recv in un thread separato, e nel main controllo > quanto tempo ci impiega. Se passano troppi secondi allora la connessione o è > troppo lenta o è caduta e quindi posso "uccidere" il recv e procedere con un > nuovo socket.accept. > > La prima soluzione potrebbe rallentare lo scambio dati e, anche se con minor > probabilità, potrebbe presentare lo stesso problema iniziale. La seconda > soluzione mi sembra un po' più generica ma non so se sia implementabile... > > Forse il mio stupore è dovuto alla mia ignoranza, ma mi stupisce che pur > settando un timeout finito il comando recv non va in timeout quando c'è una > caduta improvvisa della connessione... >
ignoranza e' una parola grossa, soprattutto nel nostro settore, ma di sicuro i socket sono una componente cosi' importante dell'informatica che conoscerli un po' meglio non farebbe male :) Comunque non mi dilungo in teoria, e ti spiego direttamente come fare. Hai bisogno (prima di read/recv) di sapere se c'e' qualcosa nel socket (se c'e' allora la chiamata successiva non sara' bloccante). Per farlo hai le funzioni di sistema select/poll e il loro equivalente ultra-fico-mega-scalabile-nonstandard epoll/kqueue/port (in base al sistema operativo su cui sei) Io ti consiglio di partire con poll() che e' la piu' semplice di tutte. Quindi l'approccio e': 1) fai una chiamata a poll() passandogli il filedescriptor a cui sei interessato (il socket) e il timeout. 2) se poll() restituisce 0 c'e' stato il timeout e allora chiudi la connessione e addio 3) se restituisce >0 allora ci sono dati nel socket e puoi leggerli tranquillamente senza paura di bloccare tutto poll e' gestita in python da questo modulo: http://docs.python.org/library/select.html qui ci sono un bel po' di esempi: http://www.doughellmann.com/PyMOTW/select/ -- Roberto De Ioris http://unbit.it _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python