MODULO 07 · CLASSE QUARTA

Reti e Socket

Programmazione TCP/UDP in Python: un server che riceve dati, li passa a un modello predittivo e risponde al client

🎯 Obiettivi del modulo

1. TCP vs UDP: due filosofie

In Sistemi e Reti hai già visto la teoria del modello TCP/IP. Qui la mettiamo in pratica con Python.

CaratteristicaTCPUDP
ConnessioneOrientato alla connessioneSenza connessione
AffidabilitàGarantita (conferma, ritrasmissione)Non garantita
VelocitàPiù lentoPiù veloce
Uso tipicoRichiesta/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.

2. Un socket server minimale

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"))

Il client corrispondente

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}")

3. Server predittivo: il modello "diventa" un servizio di rete

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"))
Collegamento con il Modulo 06: se il server dovesse gestire più client contemporaneamente, ogni connessione andrebbe gestita in un thread separato con threading.Thread(target=gestisci_client, args=(conn,)) — esattamente il pattern I/O-bound visto nel modulo precedente.

4. Dal socket all'API REST

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.

💪 Esercizi

  1. Facile: crea un server echo che restituisce esattamente il messaggio ricevuto dal client, in maiuscolo.
  2. Medio: collega il socket server al modello di regressione lineare del Modulo 04: il client invia una feature numerica, il server risponde con la previsione.
  3. Difficile: estendi il server con 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.

📌 Riepilogo

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.

← Modulo 06: Concorrenza e Parallelismo Progetto Finale →