Sockets

La comunicazione tra diversi entità in una rete è basata su Python dal classico concetto di socket. I sockets sono un concetto astratto con il quale si designa la fine di una connessione.
I programmi utilizzano i socket per comunicare con altri programmi, che possono essere trovati su computer diversi.
Uno socket è definito dall’indirizzo IP della macchina, la porta in ascolto ed il protocollo usato.
Tipi e Funzioni
I tipi e le funzioni necessarie per lavorare con i socket in Python si trovano nel modulo socket, come non potrebbe essere altrimenti.
I socket sono classificati in sockets di flusso (socket.SOCK_STREAM) o sockets datagram (socket.SOCK_DGRAM) a seconda se il servizio utilizza TCP, che è orientato alla connessione o UDP, rispettivamente. Questo capitolo coprirà i sockets di flusso, che coprono il 90% dei bisogni comuni.
I sockets possono essere classificati anche in base alla famiglia. Ci sono i sockets UNIX (socket.AF_UNIX) che sono stati creati prima del concetto di reti e si basano sui files; i socket.AF_INET che sono quelli che ci interessano; i socket.AF_INET6 per IPv6, ecc.
Per creare un socket si utilizza il costruttore socket.socket() che può prendere come parametri opzionali la famiglia, il tipo e il protocollo. Come valore predefinito si utilizza la famiglia AF_INET e il tipo SOCK_STREAM.
Vedremo durante il resto del capitolo come creare un paio di programmi client e server come esempi.
La prima cosa da fare è creare un oggetto per il socket lato server:
		socket_s = socket.socket()
Dobbiamo ora indicare quale porta si metterà in ascolto il nostro server utilizzando il metodo bind. Per i socket IP, come nel nostro caso, l’argomento di bind è una tupla che contiene l’host e la porta. Lo host può essere lasciato vuoto, indicando al metodo che può utilizzare qualsiasi nome disponibile.
		socket_s.bind(("localhost", 9999))
Infine, utilizziamo listen per fare in modo che il nostro socket accetti connessioni in ingresso e accept per iniziare l’ascolto. Il metodo listen richiede un parametro che indica il numero massimo di connessioni che si desidera accettare, naturalmente, questo valore deve essere almeno 1.
Il metodo accept rimane in attesa per le connessioni in entrata, bloccando l’esecuzione fino a quando arrivi un messaggio.
Quando arriva un messaggio, accept sblocca l’esecuzione, restituendo un oggetto socket che rappresenta la connessione client e una tupla che contiene lo host e la porta della connessione.
		socket_s.listen(10)
		socket_c, (host_c, porto_c) = socket_s.accept()
Una volta che abbiamo questo oggetto socket siamo in grado di comunicare con il client attraverso di esso, utilizzando i metodi recv e send (o recvfrom e sendfrom con l’UDP) che permettono di ricevere o inviare messaggi, rispettivamente. Il metodo send prende come parametri i dati da inviare, mentre il metodo recv accetta come parametro il numero massimo di byte da accettare.
		ricevuto = socket_c.recv(1024)
		print "Ricevuto: ", ricevuto
		socket_c.send(ricevuto)
Una volta che abbiamo terminato di lavorare con il socket, lo chiudiamo con il metodo close.
Creare un client è ancora più semplice. Dobbiamo solo creare l’oggetto socket, utilizzare il metodo connect per connetterci al server e utilizzare i metodi send e recv, che abbiamo visto in precedenza. L’argomento di connect è una tupla con lo host e la porta, come si fa’ con bind.
		socket_c = socket.socket()
		socket_c.connect(("localhost", 9999))
		socket_c.send("hola")
Vediamo infine un esempio completo. In questo esempio, il client invia al server qualunque messaggio che scriva l’utente e il server non fa’ altro che ripetere il messaggio ricevuto. L’esecuzione termina quando l’utente scrive quit.
Questo sarebbe il codice dello script per il server:
		import socket
		s = socket.socket()
		s.bind(("localhost", 9999))
		s.listen(1)
		sc, addr = s.accept()
		while True:
		    ricevuto = sc.recv(1024)
		    if ricevuto == "quit":
		        break
		    print "Ricevuto:", ricevuto
		    sc.send(ricevuto)
		print "Ciao"
		sc.close()
		s.close()
E poi abbiamo lo script per il client:
		import socket
		s = socket.socket()
		s.connect(("localhost", 9999))
		while True:
		    messaggio = raw_input("> ")
		    s.send(messaggio)
		    messaggio == "quit":
		        break
		print "Ciao"
		s.close()


Similari
Overloading di metodi in Java
12% Java
Un metodo overload viene utilizzato per riutilizzare il nome di un metodo ma con argomenti diversi, opzionalmente con un differente tipo di ritorno. [expand title=”Regole per overload” startwrap=”” endwrap=”” excerpt=”⤽” s…
Modi di fare e di non fare in Python
11% Python
Questo documento può essere considerato un compagno del tutorial di Python. Viene illustrato come utilizzare Python, e quasi ancora più importante, come non usare Python. [expand title=”Costrutti del linguaggio che non dov…
redirect 301 usando mod_alias
9% Server
mod_alias è fondamentalmente la versione più semplice di mod_rewrite. Non può fare le cose che fa mod_rewrite, ad esempio modificare la stringa di query. Per eseguire reindirizzamenti nel server web Apache è possibile di u…
Installare Python e Django su Windows
8% Django
Quando ci riferiamo allo sviluppo web con Python, la prima cosa che viene in mente è usare un qualche framework. Il più famoso e utilizzato da tutti è il Django, ma non è l’unico. Ci sono Pylons, Grok, TurboGears e Zope: t…
Metodi magici e costanti predefinite in PHP
8% Php
PHP fornisce un insieme di costanti predefinite e metodi magici per i nostri programmi. A differenza delle normali costanti i quali si impostano con define(), il valore delle costanti predefinite o speciali dipendono da do…