Programmazione TCP/UDP in Python: un server che riceve dati, li passa a un modello predittivo e risponde al client
socketIn Sistemi e Reti hai già visto la teoria del modello TCP/IP. Qui la mettiamo in pratica con Python.
| Caratteristica | TCP | UDP |
|---|---|---|
| Connessione | Orientato alla connessione | Senza connessione |
| Affidabilità | Garantita (conferma, ritrasmissione) | Non garantita |
| Velocità | Più lento | Più veloce |
| Uso tipico | Richiesta/risposta affidabile (il nostro server predittivo) | Streaming, dati in tempo reale tolleranti a perdite |
Per un server che riceve dati ed esegue una previsione, vogliamo la certezza che il messaggio arrivi integro: usiamo TCP.
import socket
HOST = "127.0.0.1"
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.bind((HOST, PORT))
server.listen()
print(f"Server in ascolto su {HOST}:{PORT}")
while True:
conn, addr = server.accept()
with conn:
print(f"Connesso da {addr}")
dati = conn.recv(1024).decode("utf-8")
print(f"Ricevuto: {dati}")
risposta = f"Server ha ricevuto: {dati}"
conn.sendall(risposta.encode("utf-8"))import socket
HOST = "127.0.0.1"
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
client.connect((HOST, PORT))
client.sendall("5.2".encode("utf-8"))
risposta = client.recv(1024).decode("utf-8")
print(f"Risposta dal server: {risposta}")Ora colleghiamo il socket server a un modello di regressione già addestrato nei moduli precedenti (es. con scikit-learn). Il client invia un valore numerico, il server lo passa al modello e rimanda la previsione.
import socket
import pickle
import numpy as np
# Modello già addestrato e salvato nei moduli precedenti (es. regressione)
with open("modello_regressione.pkl", "rb") as f:
modello = pickle.load(f)
HOST = "127.0.0.1"
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.bind((HOST, PORT))
server.listen()
print(f"Server predittivo in ascolto su {HOST}:{PORT}")
while True:
conn, addr = server.accept()
with conn:
dati = conn.recv(1024).decode("utf-8")
try:
valore = float(dati)
X = np.array([[valore]])
previsione = modello.predict(X)[0]
risposta = f"Previsione: {previsione:.2f}"
except ValueError:
risposta = "Errore: invia un numero valido"
conn.sendall(risposta.encode("utf-8"))threading.Thread(target=gestisci_client, args=(conn,)) — esattamente il pattern I/O-bound visto nel modulo precedente.
Questo schema — client che invia dati, server che risponde con una previsione — è concettualmente identico a un'API web: solo il "trasporto" cambia. In Quinta vedrai come lo stesso principio si costruisce con FastAPI/Flask su HTTP, rendendo il modello accessibile anche da un browser o da una pagina JavaScript. Il socket server di oggi è la base "grezza" su cui si costruiscono le API REST di domani.
threading per gestire più client in parallelo, e fai in modo che il client possa inviare più valori consecutivi nella stessa connessione, ricevendo una previsione per ciascuno.Il modulo socket permette di far comunicare due programmi in rete usando TCP (affidabile) o UDP (veloce ma non garantito). Collegando un socket server a un modello predittivo già allenato, trasformiamo il modello in un vero servizio di rete — il primo passo verso le API REST che costruirai in Classe Quinta.