⚖️ Differenze rispetto a UDP
🖥️ Comandi per il Server TCP
1
Creazione del socket TCP
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.SOCK_STREAMspecifica l’uso di TCP
2
Associazione e ascolto
server.bind(("127.0.0.1", 8080))
server.listen(5)
bind()assegna IP e portalisten(5)imposta la coda massima di connessioni in attesa
3
Accettazione di una connessione
conn, addr = server.accept()
print(f"Connessione accettata da {addr}")
4
Ricezione e invio di dati
data = conn.recv(1024).decode()
print("Messaggio ricevuto:", data)
conn.send("Risposta dal server".encode())
5
Chiusura del socket
conn.close() server.close()
💻 Comandi per il Client TCP
1
Creazione del socket TCP
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2
Connessione al server
client.connect(("127.0.0.1", 8080))
3
Invio di un messaggio
client.send("Ciao server TCP!".encode())
4
Ricezione della risposta
data = client.recv(1024).decode()
print("Risposta dal server:", data)
5
Chiusura del socket
client.close()
💡 Esempi Base
Server TCP Base
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8080))
server.listen(5)
print("Server in ascolto...")
conn, addr = server.accept()
print(f"Connessione da {addr}")
data = conn.recv(1024).decode()
print("Dati ricevuti:", data)
conn.send("Messaggio ricevuto".encode())
conn.close()
server.close()
Client TCP Base
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8080))
print("Connesso al server")
client.send("Ciao server!".encode())
response = client.recv(1024).decode()
print("Risposta:", response)
client.close()
🔹 Uso di with
L’uso di with in Python è fondamentale per la gestione automatica delle risorse, garantendo che il socket venga chiuso correttamente anche in caso di errori.
Perché usare with?
- Previene porte bloccate: chiude automaticamente il socket
- Gestione delle eccezioni: rilascia risorse anche in caso di errore
- Codice più pulito: non serve chiamare esplicitamente
close()
Server con with
import socket
HOST = '127.0.0.1'
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
print(f"Server su {HOST}:{PORT}")
conn, addr = s.accept()
with conn:
print(f"Connesso da {addr}")
while True:
data = conn.recv(1024)
if not data:
break
print(f"Ricevuto: {data.decode()}")
conn.sendall(data)
Client con with
import socket
HOST = '127.0.0.1'
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, Server!')
data = s.recv(1024)
print(f"Risposta: {data.decode()}")
🚀 Progetti Avanzati
🔐 Server di Login e Registrazione
Server che gestisce autenticazione utenti con dizionario username/password.
import socket
users = {
"alice": "password123",
"bob": "qwerty",
"pako": "abcd1234"
}
def client_funz(conn):
conn.sendall(b"Benvenuto! Digita LOGIN, REGISTER o DELETE:\n")
while True:
scelta = conn.recv(1024).decode().strip().upper()
if scelta == "LOGIN":
conn.sendall(b"Username e password separati da spazio:\n")
data = conn.recv(1024).decode().strip().split()
if len(data) == 2:
username, password = data
if username in users and users[username] == password:
conn.sendall(b"Accesso riuscito\n")
break
else:
conn.sendall(b"Accesso negato. Riprova:\n")
else:
conn.sendall(b"Formato errato. Usa: username password\n")
elif scelta == "REGISTER":
conn.sendall(b"Nuovo username e password:\n")
data = conn.recv(1024).decode().strip().split()
if len(data) == 2:
username, password = data
if username not in users:
users[username] = password
conn.sendall(b"Registrazione completata\n")
break
else:
conn.sendall(b"Utente esistente. Riprova:\n")
elif scelta == "DELETE":
conn.sendall(b"Username e password per cancellazione:\n")
data = conn.recv(1024).decode().strip().split()
if len(data) == 2:
username, password = data
if username in users and users[username] == password:
del users[username]
conn.sendall(b"Utente eliminato\n")
break
conn.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 65432))
server.listen()
print("Server in ascolto...")
while True:
conn, addr = server.accept()
client_funz(conn)
import socket
def client_program():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 65432))
while True:
message = client.recv(1024).decode()
print(message)
if "Accesso riuscito" in message or "Utente eliminato" in message or "Registrazione completata" in message:
break
risp = input("> ")
client.sendall(risp.encode())
client.close()
if __name__ == "__main__":
client_program()
📁 File Transfer Client-Server
Sistema per trasferire file tra dipendenti senza email o cloud.
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 65432))
server.listen()
while True:
conn, addr = server.accept()
filename = conn.recv(1024).decode()
with open(filename, "wb") as f:
while True:
data = conn.recv(1024)
if not data:
break
f.write(data)
conn.close()
Client
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 65432))
filename = "documento.txt"
client.sendall(filename.encode())
with open(filename, "rb") as f:
data = f.read(1024)
while data:
client.sendall(data)
data = f.read(1024)
client.close()
🎯 Esercitazione
Obiettivo: Creare un semplice servizio di chat tra client e server.
- Modificare il codice in modo che il server possa gestire più client contemporaneamente
- Implementare un meccanismo per terminare la connessione in modo pulito
- Permettere ai client di inviare più messaggi senza dover riavviare la connessione
🚀 Altre Lezioni
Continua il tuo percorso sui socket in Python
📚 Percorso Formativo
Completa il tuo percorso sui socket in Python