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

Rispondere a