TP - Chapitre 6 : Communiquer en réseau

N.B. Niveau : Première Générale, enseignement de spécialité NSI (Numérique et Sciences Informatiques)

Chapitre 6 - Communiquer en réseau

Les applications et jeux en réseau se basent sur le modèle clients/serveur.

Au niveau de la programmation, il faut avoir des connaissances en réseau (module socket)

Un socket permet de connecter deux machines à travers un réseau.
Dans le cas du réseau Internet, les sockets se servent du protocole IP (couche réseau) et du protocole TCP pour la couche transport (il existe aussi le protocole UDP qui est plus simple, plus rapide mais non fiable).

Exercice 6.1 : Communication entre 2 ordinateurs (ping):

Le serveur

Avant toute chose, il faut lancer le serveur. Le port par défaut est 50000. Mais on peut choisir pour le numéro de port une valeur arbitraire comprise entre 49152 et 65535.

Script coté serveur

# Script machine Serveur A LANCER EN PREMIER
# Envoi de recevoir les messages envoyés par le client ClientSimple.py


import socket
port = 50000

IP = socket.gethostbyname(socket.gethostname()) # Récupère l'adresse IP
print("Connceter le client à l'adresse IP : ", IP, " et le PORT : ", port)
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Déclaration de la connexion réseau
socket.bind((IP,port)) # Créer le lien réseau

socket.listen(5) # Ecoute le réseau
client, adresse = socket.accept() # Attend la connexion d'un client
print ("adresse IP adresse client : ", adresse[0])
print ("PORT Client : ", adresse[1])

while True:
message = client.recv(255) # Reçoit les données envoyées
message = message.decode("utf8") # décode les données
if message == "":
break
print (message)
print ("Fin")
client.close() # Ferme les connexions réseau
socket.close()

Le client

Ici, on comunique uniquement en réseau local (chez vous, derrière votre box, par exemple ou sur les ordinateurs du lycée).
Pour se connecter au serveur, il faut connaître son adresse IP (10.129.x.y) et le port qu'il utilise.

Python étant multiplateforme, on peut mélanger les systèmes d'exploitation : Windows, Linux, Mac...

Script côté client
# Script machine Client 
# Envoi de message vers le serveur serveurSimple.py

import socket

hote = input("Saisir l'adresse IP du serveur : ") # Adresse IP du serveur
port = int(input("Saisir le PORT du serveur : ")) # Port du serveur

serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Déclaration de la connexion réseau
serveur.connect((hote, port)) # Etablir la connexion avec le serveur
print ("Connecté au port ",port)
while(1):
message=input("Message à envoyer : ")
serveur.send(message.encode("utf8")) # Envoie le message vers le serveur
if message=="":
break
print ("Fin")

serveur.close() # Ferme la connexion réseau

Avec ces deux scripts, faire communiquer votre ordinateur avec l'ordinateur de votre voisin.

Faire valider par le professeur

Exercice 6.2 : Communication "ping - pong" :

Enregistrer les scripts précédents : client.py sous clientPing.py et serveur.py sous serveurPong.py
Avec ces deux scripts, la communication ne peut se faire que du client vers le serveur. 

En comparant les deux scripts, modifiez-les pour permettre au serveur et au client de communiquer à tour de rôle (Client_ping, serveur_pong) :

Faire valider par le professeur

Exercice 6.3 : Transférer des variables :

Actuellement la communication ne permet pas de transférer des données commes des variables, des listes...
La bibliothèque pickle permet d'encoder les données à transférer dans le bon format.
Reprendre les cripts de l'exercice 6.1. Enregistrer sous clientDico.py et ServeurDico.py
Ajouter dans les deux scripts au moment de l'importation :
import socket,pickle
On désire transférer des données type dictionnaire et de l'exploiter sur le serveur.

Coté client on encode les doonées contenues dans un dictionnaire avant de les transmettre
joueur={'Nom':"MBAPPE",'Prenom':"Kylian",'Matchs':[(3,0),(1,2),(2,2)]}
donnees=pickle.dumps(joueur)
...
serveur.send(donnees)
Coté serveur on décode les données reçues par le client puis on les affiche :
...
reponse = client.recv(255)
joueur=pickle.loads(reponse)
print(joueur['Nom'],' ',joueur['Prenom'])
print("Score du 2ème match :\n",joueur['Matchs'][1])
...
Adapter le code pour transférer le dictionnaire joueur du client vers le serveur.

Faire valider par le professeur

Exercice 6.4 : Space invader - le duel

On désire utiliser le même script pour jouer sur les deux ordinateurs.
Télécharger le fichier compressé suivant : SpaceReseau.zip
Décompresser les fichiers dans vos documents.

1 - Choix du rôle :

Le choix se fait par l'appel du menu qui retourne le rôle ('s' pour le serveur ou 'c' pour le client) : role=menu()

algorithme:

si la touche s est appuyée (K_s)
retouner 's'
si la touche c est appyuée (K_c)
retourer 'c'
Implanter cet algorithme dans la fonction  menu()

2 - Connexion du client au serveur

Si le rôle choisi est le serveur, on appelle la fonction connexion qui retournera l'adresse du client
Sinon la fonction retournera l'adresse du serveur.
Implanter le code permettant de connecter le client et serveur dans la fonction connexion(role)

3 - Structure des données à transmettre :

coté serveur :

coté client :

Implanter ce code dans le programme principal en remplaçant les ... par les variables ou les clés des dictionnaires.
# Déplacement du vaisseau ou de l'alien de 5 pixels     
if role =='s':
if Gauche and rectangle_vaisseau.left > 10 : rectangle_vaisseau.left -= 5
if Droite and rectangle_vaisseau.right < 440 : rectangle_vaisseau.right += 5
donnees_serveur={"Coordonnees":...,"Missiles":...,"Score":...}
donnees=pickle.dumps(donnees_serveur)
client.send(donnees)
msgClient = client.recv(1024)
msgClient = pickle.loads(msgClient)
rectangle_alien=msgClient['...']
missiles_aliens=msgClient['...']
score_client=msgClient['...']

else:
if Gauche and rectangle_alien.left > 10 : rectangle_alien.left -= 5
if Droite and rectangle_alien.right < 440 : rectangle_alien.right += 5
donnees_client ={"Coordonnees":...,"Missiles":...,"Score":...}
donnees=pickle.dumps(donnees_client)
msgServeur=serveur.recv(1024)
msgServeur=pickle.loads(msgServeur)
serveur.send(donnees)
rectangle_vaisseau=msgServeur['...']
missiles=msgServeur['...']
score_serveur=msgServeur['...']
Faire valider par le professeur

4 - Affichage du score :

Remplacer les instructions print permettant d'afficher le score dans la console par un affichage graphique dans la fenêtre du jeu.
Faire valider par le professeur

5 - Analyse du réseau :

Exécuter Wireshark


image

cliquer sur start

Dans filtre tapez votre adresse ip avec l'instruction suivante

image

Retrouver les données transmises par le PC dans la trame.