From 9194a34902a9574aaecb6eceaf16e95c3f9da001 Mon Sep 17 00:00:00 2001 From: Dimitri Merejkowsky Date: Sat, 21 Mar 2020 11:12:44 +0100 Subject: [PATCH] Suppression du chapitre sur les sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il ira dans un autre cours, ou peut-être dans le projet depydoc lui-même --- .../index.rst | 0 cours/source/17-sockets/exemple.rst | 128 ---------------- cours/source/17-sockets/index.rst | 14 -- cours/source/17-sockets/introduction.rst | 28 ---- cours/source/17-sockets/protocoles.rst | 145 ------------------ .../01-introduction.rst | 0 .../02-décorateurs.rst | 0 .../index.rst | 0 cours/source/index.rst | 5 +- 9 files changed, 2 insertions(+), 318 deletions(-) rename cours/source/{18-classes-03 => 17-classes-03}/index.rst (100%) delete mode 100644 cours/source/17-sockets/exemple.rst delete mode 100644 cours/source/17-sockets/index.rst delete mode 100644 cours/source/17-sockets/introduction.rst delete mode 100644 cours/source/17-sockets/protocoles.rst rename cours/source/{19-functions-02 => 18-functions-02}/01-introduction.rst (100%) rename cours/source/{19-functions-02 => 18-functions-02}/02-décorateurs.rst (100%) rename cours/source/{19-functions-02 => 18-functions-02}/index.rst (100%) diff --git a/cours/source/18-classes-03/index.rst b/cours/source/17-classes-03/index.rst similarity index 100% rename from cours/source/18-classes-03/index.rst rename to cours/source/17-classes-03/index.rst diff --git a/cours/source/17-sockets/exemple.rst b/cours/source/17-sockets/exemple.rst deleted file mode 100644 index b6f6776..0000000 --- a/cours/source/17-sockets/exemple.rst +++ /dev/null @@ -1,128 +0,0 @@ -Exemple -======= - -Pour ce premier exemple, le client et le serveur vont tourner sur la même machine: la vôtre! - -Le processus du serveur tournera dans un premier terminal, et le processus du client dans un autre. - -Pour les différencier, on peut utiliser la variable `sys.ps1`. - -Étape 1 -------- - -Ouvrez deux terminaux, lancez dans chacun d'eux la commande `python3` sans arguments, puis tapez:: - - >>> import sys - >>> sys.ps1 = "(serveur) >>> " - -dans le premier, et:: - - >>> import sys - >>> sys.ps1 = "(client) >>> " - -dans le second. - -Vous devriez obtenir le résultat suivant:: - - (serveur) >>> - -:: - - (client) >>> - -Dans chacun d'eux, définissez les variables ``IP`` et ``PORT``:: - - (serveur) >>> IP = "127.0.0.1" - (serveur) >>> PORT = 3000 - -:: - - (client) >>> IP = "127.0.0.1" - (client) >>> PORT = 3000 - - -L'adresse IP ``127.0.0.1`` est spéciale et désigne votre propre machine. -Le PORT 3000 est un port arbitraire - - -Étape 2 -------- - -Dans le REPL du serveur, créez une socket du type 'AF_INET' et 'SOCK_STREAM', puis appelez -``bind()`` avec le tuple (IP, PORT) [#f1]_ :: - - - (serveur) >>> IP = "127.0.0.1" - (serveur) >>> PORT = 3000 - (serveur) >>> import socket - (serveur) >>> s_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - (serveur) >>> s_serveur.bind((IP, PORT)) - -Ensuite, appelez ``s_serveur.listen(0)``: cela permet à votre serveur d'accepter des connections:: - - (serveur) >>> s_serveur.listen(0) - -Enfin, appelez ``s_serveur.accept`: cette méthode retourne un tuple qu'on note souvent ``con, addr``:: - - (serveur) >>> con, addr = s_serveur.accept() - -Cette fois ci, vous devriez constater que le processus du serveur est *bloqué*: l'invite de commande ne s'affiche -pas - en effet, le serveur est en attente d'une connexion par le client - - -Étape 3 -------- - -De la même façon que pour le serveur, créez une socket du même type côté -client:: - - (client) >>> IP = "127.0.0.1" - (client) >>> PORT = 3000 - (client) >>> import socket - (client) >>> s_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - -Ensuite, *connectez* la socket client à la socket serveur:: - - (client) >>> s_client.connect((IP, PORT)) - -Comme par magie, vous devriez voir le processus **dans l'autre terminal** reprendre son exécution: -les deux processus Python sont donc bien en train de *communiquer* - - -Étape 4 -------- - -Vous pouvez maintenant utiliser les méthodes ``send()`` et ``recv``, respectivement avec l'objet -``con`` côté serveur, et ``s_client`` côté client pour envoyer et recevoir des messages entre -les deux processus. - -Notez que ``send`` prend des ``bytes`` en arguments et renvoie le nombre d'octets envoyés, -et que ``recv()`` prend un nombre d'octets à lire. - -On peut envoyer des message du client vers le serveur:: - - - (client) >>> s_client.send(b"Bonjour") - 7 - -:: - - (serveur) >>> con.recv(7) - b'Bonjour' - - -Et du serveur vers le client:: - - (serveur) >>> con.send(b"Comment va ?") - 12 - -:: - - (client) >>> s_client.recv(12) - b'Comment va ?' - - -.. rubric:: notes - -.. [#f1] Il existe des sockets de plusieurs type et avec des comportements différents. AF_INET et SOCK_STREAM sont - les plus courants. diff --git a/cours/source/17-sockets/index.rst b/cours/source/17-sockets/index.rst deleted file mode 100644 index 067187c..0000000 --- a/cours/source/17-sockets/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -Chapitre 17 - Sockets -===================== - -Ce chapitre n'est pas à proprement parler un cours sur le langage -Python, mais contient des éléments qui nous servirons à bâtir -un projet à long terme : fabriquer un site Web ! - - -.. toctree:: - :maxdepth: 1 - - introduction - exemple - protocoles diff --git a/cours/source/17-sockets/introduction.rst b/cours/source/17-sockets/introduction.rst deleted file mode 100644 index 369c376..0000000 --- a/cours/source/17-sockets/introduction.rst +++ /dev/null @@ -1,28 +0,0 @@ -Introduction -============= - -Clients et serveurs -------------------- - -Dans le chapitre 15, nous avons parlé des données binaires et évoqué le -fait que cela permettait à nos programmes Python d'intéragir avec -l'extérieur, notamment via le système de fichiers. - -Il existe dans la librairie standard une autre façon pour Python de -communiquer via *le réseau* : il s'agit du module ``socket``. - -Une communication sur le réseau Internet implique: - -* Un *client* qui va faire des *requêtes* -* Un *serveur* qui va renvoyer des *réponses* au client -* Une *adresse* du serveur utilisée par le client - -Dans notre cas, cette adresse est un *tuple*, composé de deux éléments: -une *adresse IP* et un *port*. - -.. image:: /img/client-serveur.png - -En général: - -* Le *client* et le *serveur* sont sur des machines différentes -* Il n'y a qu'un seul processus qui est capable d'écouter sur un port donné diff --git a/cours/source/17-sockets/protocoles.rst b/cours/source/17-sockets/protocoles.rst deleted file mode 100644 index 156613d..0000000 --- a/cours/source/17-sockets/protocoles.rst +++ /dev/null @@ -1,145 +0,0 @@ -Protocoles -========== - -Le problème ------------- - -Notez que ``send()`` et ``recv()`` sont très basiques: - -* On peut appeler ``send()`` plusieurs fois d'affilée -* On peut aussi appeler ``recv()`` alors que le client n'a encore rien envoyé, - le serveur va juste bloquer en attendant le prochain message du client. -* Si le client envoie 3 octets et que le serveur utilise ``recv(10)``, il n'y - a pas d'erreur -* Si le client envoie 10 octets et que le serveur utilise ``recv(3)``, il n'y - a pas non plus d'erreur, et il faut appeler ``recv()`` une deuxième fois - (avec 7 par exemple) pour récupérer le message en entier - - -Protocoles ------------ - -Ainsi, si on veut que deux machines s'échangent des messages via Internet, il faut -convenir d'un **protocole** - qui parle en premier, quel genre de message peut-il -envoyer? Il faut aussi convenir d'une façon de communiquer la *taille* des réponses. - - - -Le protocole HTTP ------------------ - -Le protocole HTTP est relativement simple. On peut le vérifier en essayant -de se connecter à l'adresse ``(93.184.216.34, 80)``, et envoyant les messages -suivants - à l'heure où j'écris ces lignes, l'IP ci-dessus correspond au site -``http://example.com`` :: - - import socket - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect(("93.184.216.34", 80)) - s.send(b"GET / HTTP/1.1\r\n") - s.send(b"Host: example.com\r\n") - s.send(b"\r\n") - - message = s.recv(351).decode() - print(message) - - -Résultat: - -.. code-block:: text - - HTTP/1.1 200 OK - Age: 514391 - Cache-Control: max-age=604800 - Content-Type: text/html; charset=UTF-8 - Date: Sun, 01 Mar 2020 15:57:23 GMT - Etag: "3147526947+ident" - Expires: Sun, 08 Mar 2020 15:57:23 GMT - Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT - Server: ECS (bsa/EB18) - Vary: Accept-Encoding - X-Cache: HIT - Content-Length: 1256 - - - - -Notez qu'on a appelé `.decode()` sur le message reçu du serveur - on dit que HTTP -est un protocole de *texte*. - -Notez que la réponse du serveur rappelle le nom du protocole ``HTTP/1.1`` et répond avec -de nombreuses lignes contenant une *clé* et une *valeur* séparé par des deux-points - -On appelle cela des *en-têtes* (ou *headers*). L'un d'eux contient la taille totale du -message: ``Content-Length: 1256``. - -Après le bloc de headers, on voit le *corps* de la réponse: quelque chose qui commence -par ````. - -On peut lire la suite du message:: - - - suite = s.recv(1000).decode() - print(suite) - -.. code-block:: text - - - - Example Domain - - - - - - - - -
-

Example Domain

-

This domain is for use in illustrative examples in documents. You may use this - domain in literature without prior coordination or asking for permission.

-

More information...

-
- - - - -Si maintenant vous allez sur ``https://example.com`` avec un navigateur Web, et cliquez sur -"Afficher le code source de la page", vous devriez voir exactement le contenu ci-dessus. - -Cela prouve que: - -* Il y a un serveur qui écoute sur l'adresse IP de example.com, sur le port 80 -* Ce serveur comprend le protocole HTTP -* Un navigateur ne fait rien d'autre que: - * envoyer des requêtes HTTP vers un serveur - * interpréter le texte retourné et l'afficher -* On peut facilement coder à la fois des *clients* et des *serveur* HTTP en Python, juste avec le module socket. - diff --git a/cours/source/19-functions-02/01-introduction.rst b/cours/source/18-functions-02/01-introduction.rst similarity index 100% rename from cours/source/19-functions-02/01-introduction.rst rename to cours/source/18-functions-02/01-introduction.rst diff --git a/cours/source/19-functions-02/02-décorateurs.rst b/cours/source/18-functions-02/02-décorateurs.rst similarity index 100% rename from cours/source/19-functions-02/02-décorateurs.rst rename to cours/source/18-functions-02/02-décorateurs.rst diff --git a/cours/source/19-functions-02/index.rst b/cours/source/18-functions-02/index.rst similarity index 100% rename from cours/source/19-functions-02/index.rst rename to cours/source/18-functions-02/index.rst diff --git a/cours/source/index.rst b/cours/source/index.rst index b8a5ff3..8f81d0e 100644 --- a/cours/source/index.rst +++ b/cours/source/index.rst @@ -33,6 +33,5 @@ remarques. 14-bibliothèques-01/index 15-fichiers-et-données-binaires/index 16-interpréteur-interactif/index - 17-sockets/index - 18-classes-03/index - 19-functions-02/index + 17-classes-03/index + 18-functions-02/index