L'idea alla base dello scambio dati e':
- il server crea un socket e resta in ascolto
- il client si connette, chiede info e riceve la risposta
- il server distrugge il socket e ne crea uno nuovo "pulito" su cui restare in ascolto e il tutto si ripete
Finora la dimensione massima della risposta era variabile, ma comunque inferiore a 2kbyte per cui sul client mettevo un bel
- Codice: Seleziona tutto
risposta=sock.recv(2048) # al max ricevo 2kbyte
Adesso mi hanno cambiato le specifiche per cui mi sono ritrovato risposte lunghe piu' dei 2k preimpostati (inferiori a 4, in ogni caso).
Bello come il sole ho pensato che mettendo
- Codice: Seleziona tutto
risposta=sock.recv(4096)
La comunicazione via socket non e' poi cosi' "deterministica": il server spedisce 4k, ma non e' detto che li spedisca tutti insieme, magari decide di prendersi una pausa, di lasciarne un po' indietro, di tenersene un po' per la prossima volta, di portarne un po' a sua madre (dato che domenica scorsa si e' dimenticato che era la sua festa)...
Per cui il client non puo' sapere se deve restare ad aspettarsi ancora qualcosa o meno. E questo nonostante sul server usassi sendall() invece di send()... E infatti ogni tanto andava tutto bene, ma molto piu' spesso ricevevo risposte di 1448 byte (credo dipenda dai buffer del sistema)
Dato che per i socket non esiste l'analogo dell'EOF c'e' chi suggerisce di mettere una doppia gestione della risposta (prima ti invio la lunghezza della risposta e poi la risposta stessa, pero' anche qui ci possono essere problemi: e se non mi arriva tutta la prima parte?) e incasinarsi il codice (e la vita)...
La soluzione semplice ed elegante e' usare un file associato al socket, che si riesce a gestire molto piu' agevolmente:
- Codice: Seleziona tutto
filesock = sock.makefile('r',0) # r = in lettura; 0 = non bufferizzato
risposta = filesock.read() # posso anche leggere una riga alla volta, con filesock.readline()
e adesso non sbaglia piu' un colpo!
hth