Oggi voglio riportarvi un esempio di come funziona e come si implementa il broadcast dei pacchetti in python. Prima di iniziare, ricordo a chi non lo sapesse che oltre ai socket TCP (SOCK_STREAM) i quali garantiscono (usando il protocollo tcp) che i dati che vengono trasmessi arrivano correttamente a destinazione, esistono i socket udp (SOCK_DGRAM) i quali non danno nessuna garanzia (esistono anche altri tipi di socket di cui non ci preoccuperemo in questo post). I socket tcp non permettono il broadcast in quanto sono socket basati sulla connessione. Quelli udp invece consentono il broadcast perché sono connection-less. Vi riporto ora un esempio davvero semplice di un broadcast server e di un client che riceve informazioni dal server.
#server
PORT = 50000
import sys, time
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('', 0))
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
while 1:
try:
data = repr(time.time())
# non funziona se non c'e' un default
# routing
#s.sendto(data, ('<broadcast>', PORT))
# se invece specifico un indirizzo di
# broadcast funziona
s.sendto(data, ('192.168.0.255', PORT))
time.sleep(2)
except KeyboardInterrupt:
sys.exit(0)
Come potete vedere il codice del server è molto banale. In pratica non fa altro che mandare in broadcast ogni 2 secondi il tempo misurato dal sistema. Notiamo che stiamo usando i datagram sockets e li abbiamo messi in modalità broadcast con
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
A questo punto notate il commento sull'istruzione che usa <> come indirizzo al quale inviare i dati. Sul manuale di python questo non è specificato ma è così. Se vogliamo che i dati vengano ricevuti dal client dobbiamo specificare l'indirizzo di broadcast corretto.
Vediamo ora il codice del client:
Come possiamo notare il client non conosce a priori l'indirizzo del server ma riceve semplicemente i dati. Ricordiamoci comunque che il protocollo udp non garantisce nulla sulla consegna degli stessi. Quindi è possibile che ciò che invia il server non arrivi correttamente a destinazione
import sys
from socket import *
PORT = 50000
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('', PORT))
while 1:
try:
data, fromaddr = s.recvfrom(1024)
print (data, fromaddr)
except KeyboardInterrupt:
sys.exit(0)
Nessun commento:
Posta un commento