|
|
|
La libreria di riferimento di Python |
|
|
|
Il modulo SocketServer semplifica il compito di scrivere
server di rete.
Esistono quattro classi di base per i server: TCPServer, che
utilizza il protocollo Internet TCP, che fornisce un flusso continuo
di dati tra il client e il server. UDPServer, che utilizza i
datagrammi, che sono pacchetti discreti di informazioni che possono
arrivare fuori ordine o possono essere persi durante la trasmissione.
I meno utilizzati UnixStreamServer e
UnixDatagramServer, che sono simili, ma utilizzano i socket
domain di Unix; non sono disponibili su piattaforme non Unix.
Per maggiori dettagli sulla programmazione di rete, consultare un
testo come lo UNIX Network Programming di W.Richard Steven
o il Win32 Network Programming di Ralph Davis.
Queste quattro classi elaborano richieste in modalità sincrona;
ogni richiesta deve essere completata prima che la richiesta
successiva possa iniziare. Questo non è adatto se ogni richiesta
richiede molto tempo per essere completata, perché neccessita di parecchio
calcolo, o perché restituisce molti dati ed il client è lento ad
elaborarli. La soluzione è quella di creare un processo separato o
un thread per gestire ogni richiesta; Le classi mix-in
ForkingMixIn e ThreadingMixIn possono essere usate per
supportare compiti asincroni.
Creare un server richiede diversi passaggi. Per prima cosa, si deve
creare una classe handler (Ndt. gestore) di richiesta derivandola da
BaseRequestHandler e sovrascrivendo il metodo
handle(); questo metodo elaborerà le richieste in ingresso.
Secondo, si devono istanziare una o più classi di server, passandogli
l'indirizzo del server e le classi degli handler di richiesta.
Infine, si deve chiamare il metodo handle_request() o
serve_forever() dell'oggetto server per elaborare una o
molte richieste.
Quando si eredita da ThreadingMixIn per avere delle
connessioni in thread, si deve esplicitamente dichiarare come si vuole
il proprio thread per evitare di ottenere una brusca interruzione. La
classe ThreadingMixIn definisce un attributo
daemon_threads, che indica se il server deve attendere
un'interruzione del thread oppure no. Si deve impostare l'opzione
esplicitamente se si vuole che i thread siano autonomi; il valore
predefinito è False, che significa che Python non uscirà
finché tutti i thread creati da ThreadingMixIn non siano
terminati.
Le classi server hanno gli stessi metodi ed attributi esterni,
indipendentemente dal protocollo che utilizzano.
-
Restituisce un descrittore file intero per il socket su cui il server
è in ascolto. La funzione è abitualmente passata a
select.select(), per consentire il monitoraggio di server
multipli nello stesso processo.
-
Elabora una richiesta singola. Questa funzione chiama i seguenti
metodi nell'ordine: get_request(), verify_request()
e process_request(). Se il metodo indicato, fornito
dall'utente handle() della classe handler solleva
un'eccezione, verrà chiamato il metodo handle_error() del
server.
-
Gestisce un infinito numero di richieste. Questo semplicemente chiama
handle_request() all'interno di un ciclo infinito.
- address_family
-
La famiglia di protocolli a cui il socket del server appartiene.
socket.AF_INET e socket.AF_UNIX sono due
possibili valori.
- RequestHandlerClass
-
la classe handler fornita dall'utente; un'istanza di questa classe
viene creata per ogni richiesta.
- server_address
-
L'indirizzo su cui il server è in ascolto. Il formato degli indirizzi
varia in base alla famiglia del protocollo; vedere la documentazione
del modulo socket per i dettagli. Per i protocolli internet, questo è
una tupla contenente una stringa indicante l'indirizzo ed il numero di
porta come intero: per esempio:
('127.0.0.1', 80)
.
- socket
-
L'oggetto socket su cui il server sarà in ascolto per le richieste in
arrivo.
La classe server supporta le seguenti variabili di classe:
- allow_reuse_address
-
Quando il server consente di riutilizzare un indirizzo. Il suo valore
predefinito è
False
e può essere impostato in una sotto classe
per cambiare la policy.
- request_queue_size
-
La dimensione della coda di richiesta. Se il server richiede
parecchio tempo per elaborare una singola richiesta, ogni richiesta
che arriva quando il server è occupato viene inserita in una coda,
fino al raggiungimento di request_queue_size. Una volta che
la coda è piena, successive richieste dal client riceveranno un errore
``Connection denied'' (Ndt. Connessione negata). Il valore predefinito tipicamente è
5
,
ma questo può essere sovrascritto con una sotto classe.
- socket_type
-
Il tipo di socket usato dal server; socket.SOCK_STREAM
e socket.SOCK_DGRAM sono due possibili valori.
Ci sono diversi metodi della classe server che possono essere
sovrascritti da sotto classi delle classi server come
TCPServer; questi metodi non sono utili per le utenze esterne
all'oggetto server.
-
Attualmente elabora la richiesta istanziando
RequestHandlerClass e chiamandone il metodo
handle().
-
Deve accettare una richiesta dal socket, e restituire una tupla di due
elementi contenente il nuovo oggetto socket da usare per
comunicare con il client e l'indirizzo del client.
handle_error( |
request, client_address) |
-
La funzione viene chiamata se il metodo handle() di
RequestHandlerClass solleva un'eccezione. L'azione
predefinita è stampare la traceback sullo standard output e continuare
a gestire le richieste successive.
process_request( |
request, client_address) |
-
Chiama finish_request() per creare un'istanza di
RequestHandlerClass. Se lo si desidera, questa funzione può
creare un nuovo processo o un nuovo thread per gestire la richiesta;
le classi ForkingMixIn e ThreadingMixIn fanno questo.
-
Chiamato dal costruttore del server per attivare il server. Può
essere sovrascritto.
-
Chiamato dal costruttore del server per gestire il socket
all'indirizzo desiderato. Può essere sovrascritto.
verify_request( |
request, client_address) |
-
Deve restituire un valore Booleano; se il valore è vero, la richiesta
verrà elaborata, e se è falsa, la richiesta verrà negata. La
funzione può essere sovrascritta per implementare il controllo degli
accessi al server. L'implementazione predefinita restituisce sempre
vero.
La classe handler di richiesta deve definire un nuovo metodo
handle() e può sovrascrivere uno dei seguenti metodi. Una
nuova istanza viene creata per ogni richiesta.
-
Chiamato dopo il metodo handle() per eseguire ogni azione di
pulizia richiesta. L'implementazione predefinita non fa nulla. Se
setup() o handle() sollevano un'eccezione, questa
funzione non verrà chiamata.
-
Questa funzione deve fare tutto il lavoro richiesto per servire una
richiesta. Molti attributi dell'istanza sono disponibili; la
richiesta è disponibile come self.request; l'indirizzo del
client è self.client_address; e l'istanza del server come
self.server, in caso avesse bisogno di accedere ad
informazioni del server.
Il tipo di self.request è differente per i datagrammi o
flussi di servizi. Per servizi di flussi, self.request è un
oggetto socket; per i servizi di datagrammi, self.request è
una stringa. Comunque, questo può essere nascosto usando le classi
handler di richiesta mix-in StreamRequestHandler o
DatagramRequestHandler, che sovrascrivono i metodi
setup() e finish(), e forniscono gli attributi
self.rfile e self.wfile. self.rfile e
self.wfile possono essere letti o scritti, rispettivamente,
per acquisire i dati richiesti o restituirli al client.
-
Chiamato prima del metodo handle() per eseguire ogni
richiesta della sequenza di inizializzazione. L'implementazione
predefinita non fa nulla.
|
|
|
La libreria di riferimento di Python |
|
|
|
Release 2.3.4, documentation updated on 21. maggio 2005.
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.