TP3

Programmation UDP

1. Prélude

Vous devez rendre tout ce que vous avez obtenu pendant le TP, sur arche

Vous pouvez le finir chez vous, ou le rendre à la fin du TP.

2. Découverte

  • Récupérez l'archive TP3.zip sur arche et décompressez-là.

  • Compilez le .c et lancez-le

  • Sur la même machine, mais dans un autre terminal, lancez la commande

    python3 client.py
    

  • Cette commande a lancé un client qui s'est connecté au serveur (écrit en C). En lisant le code de client.py découvrez sur quel port se trouve le serveur.

  • Modifiez le programme client.py pour qu'on puisse rentrer l'adresse IP et le port du destinataire en arguments. (Une aide python est disponible en fin de sujet)

  • Vérifiez que votre nouveau programme fonctionne. Pour cela, lancez le serveur sur votre propre machine, et le client sur une autre machine, avec l'aide de ssh.

  • Modifiez le programme client.py pour gérer les erreurs (afficher l'erreur et quitter le programme). Attention, il faut réfléchir à toutes les sources possibles d'erreur.

3. Serveur

  • Ecrire un serveur server.py compatible avec votre client. Le serveur doit afficher l'IP et le port du client.

  • Vérifiez que votre serveur fonctionne.

  • Modifiez le serveur pour qu'il mette le message du client en majuscule. Pour cela, on pourra utiliser la fonction s.upper() qui met en majuscule la chaîne s (il faudra donc convertir les octets envoyés par le client en chaîne et réciproquement. Voir l'aide en fin de sujet)

    PREMIER RENDU: Les deux fichiers client.py, server.py

4. Modifications

Dans cette partie, on va écrit un client qui va envoyer deux nombres, et un serveur qui va les additionner. Attention! Quand on envoie des entiers sur le réseau, on ne les envoie pas comme des suites de caractères (par exemple, on envoie pas 16684 avec les 5 octets "1", "6", "6", "8" et "4" ), on les envoie en binaire (16684 sera codé sur 4 octets, par la suite binaire 00000000000000000100000100101100, c'est à dire par les 4 octets 0, 0 ,'A' et ','). Lisez la rubrique "Conversions" pour trouver comment faire.

  • Recopiez les fichiers server.py et client.py dans deux nouveaux fichiers serveradd.py et clientadd.py. Modifiez ces nouveaux fichiers, de sorte que le client envoie deux entiers au serveur, qui va renvoyer la somme. Le client enverra un seul message, dont les 4 premiers octets correspondront au premier entier, et les 4 octets suivant au deuxième entier (voir fonctions de conversion à la fin). Les deux entiers sont à demander au client (syntaxe: x=int(input("donner un entier")))

    DEUXIEME RENDU: Les deux fichiers clientadd.py, serveradd.py

5. Modifications 2

  • Recopiez les fichiers serveradd.py et clientadd.py dans deux nouveaux fichiers serveradd2.py et clientadd2.py. Modifiez ces nouveaux fichiers, de sorte que le client demande le premier entier, l'envoie au serveur dans un premier message, puis demande le deuxième entier, l'envoie au serveur dans un deuxième message, puis récupère le résultat (la somme) du serveur.

  • Ajoutez une boucle while au serveur afin qu'il puisse tourner indéfiniment et traiter client après client.

  • Réalisez une expérience où deux clients se connectent au serveur et n'obtiennent pas la bonne réponse.

    TROISIEME RENDU: Les deux fichiers clientadd2.py, serveradd2.py, un fichier README expliquant l'expérience réalisée

6. Modifications 3

  • Recopiez le fichier serveradd2.py dans un nouveau fichier server3.py. Trouvez comment modifier votre serveur pour éviter le problème soulevé dans l'expérience précédente.

    QUATRIEME RENDU: Les deux fichiers clientadd2.py, server3.py

7. Python

7.1. Commandes systèmes

Commandes utiles dans le module sys (faire import sys en début de programme)

  • sys.argv contient la ligne de commande. sys.argv[0] est le nom du programme, sys.argv[1] le premier argument, etc

  • sys.exit(code) permet de quitter le programme en renvoyant le code d'erreur code (en général 0 si le programme a fonctionné, -1 sinon).

7.2. Conversions

Python manipule beaucoup de types différents. Pour le cours de réseau il est important de différencier le type bytes (suite d'octets) du type str (chaîne de caractères). Toutes les fonctions réseaux (send/recv/sendto/recvfrom) manipule des bytes

  • int(s) permet de convertir une chaîne de caractère s en un entier

  • int.from_bytes(x, byteorder="big") permet de convertir une suite d'octets x en un entier

  • int.to_bytes(m,n, byteorder="big") permet de convertir un entier m en une suite d'octets de longueur exactement n.
  • str(x,"utf-8") permet de convertir une suite d'octets x en une chaîne de caractères

  • bytes(s,"utf-8") permet de convertir une chaîne de caractères s en une suite d'octets

7.3. Elements du langages

if x == 1:
  print(x+y)
else:
  print(x+1)


while x < 1664:
  print(x)
  x = x + 1

for i in range(3):
  # affiche les entiers de 0 a 2
  print(i)

for i in l:
  # si l est une liste
  print(i)

for i in range(len(l)):
  # len(l) est la longueur de la liste l
  # l[i] est le ieme element de la liste
  print(l[i])


# x est une suite de 5 octets
x = b"totoi"
#affiche l'octet numero 0
print(x[0])
#affiche les octets numero 2 a 4
print(x[2:5])

try:
  x = 3
  x = x / 0
except ZeroDivisionError as e:
  print(e, file=sys.stderr)