Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
Dieses Repo ist archiviert. Du kannst Dateien sehen und es klonen, kannst aber nicht pushen oder Issues/Pull-Requests öffnen.

protocoles.rst 4.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. Protocoles
  2. ==========
  3. Le problème
  4. ------------
  5. Notez que ``send()`` et ``recv()`` sont très basiques:
  6. * On peut appeler ``send()`` plusieurs fois d'affilée
  7. * On peut aussi appeler ``recv()`` alors que le client n'a encore rien envoyé,
  8. le serveur va juste bloquer en attendant le prochain message du client.
  9. * Si le client envoie 3 octets et que le serveur utilise ``recv(10)``, il n'y
  10. a pas d'erreur
  11. * Si le client envoie 10 octets et que le serveur utilise ``recv(3)``, il n'y
  12. a pas non plus d'erreur, et il faut appeler ``recv()`` une deuxième fois
  13. (avec 7 par exemple) pour récupérer le message en entier
  14. Protocoles
  15. -----------
  16. Ainsi, si on veut que deux machines s'échangent des messages via Internet, il faut
  17. convenir d'un **protocole** - qui parle en premier, quel genre de message peut-il
  18. envoyer? Il faut aussi convenir d'une façon de communiquer la *taille* des réponses.
  19. Le protocole HTTP
  20. -----------------
  21. Le protocole HTTP est relativement simple. On peut le vérifier en essayant
  22. de se connecter à l'adresse ``(93.184.216.34, 80)``, et envoyant les messages
  23. suivants - à l'heure où j'écris ces lignes, l'IP ci-dessus correspond au site
  24. ``http://example.com`` ::
  25. import socket
  26. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  27. s.connect(("93.184.216.34", 80))
  28. s.send(b"GET / HTTP/1.1\r\n")
  29. s.send(b"Host: example.com\r\n")
  30. s.send(b"\r\n")
  31. message = s.recv(351).decode()
  32. print(message)
  33. Résultat:
  34. .. code-block:: text
  35. HTTP/1.1 200 OK
  36. Age: 514391
  37. Cache-Control: max-age=604800
  38. Content-Type: text/html; charset=UTF-8
  39. Date: Sun, 01 Mar 2020 15:57:23 GMT
  40. Etag: "3147526947+ident"
  41. Expires: Sun, 08 Mar 2020 15:57:23 GMT
  42. Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
  43. Server: ECS (bsa/EB18)
  44. Vary: Accept-Encoding
  45. X-Cache: HIT
  46. Content-Length: 1256
  47. <!doctype html>
  48. Notez qu'on a appelé `.decode()` sur le message reçu du serveur - on dit que HTTP
  49. est un protocole de *texte*.
  50. Notez que la réponse du serveur rappelle le nom du protocole ``HTTP/1.1`` et répond avec
  51. de nombreuses lignes contenant une *clé* et une *valeur* séparé par des deux-points
  52. On appelle cela des *en-têtes* (ou *headers*). L'un d'eux contient la taille totale du
  53. message: ``Content-Length: 1256``.
  54. Après le bloc de headers, on voit le *corps* de la réponse: quelque chose qui commence
  55. par ``<!doctype html>``.
  56. On peut lire la suite du message::
  57. suite = s.recv(1000).decode()
  58. print(suite)
  59. .. code-block:: text
  60. <html>
  61. <head>
  62. <title>Example Domain</title>
  63. <meta charset="utf-8" />
  64. <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  65. <meta name="viewport" content="width=device-width, initial-scale=1" />
  66. <style type="text/css">
  67. body {
  68. background-color: #f0f0f2;
  69. margin: 0;
  70. padding: 0;
  71. font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  72. }
  73. div {
  74. width: 600px;
  75. margin: 5em auto;
  76. padding: 2em;
  77. background-color: #fdfdff;
  78. border-radius: 0.5em;
  79. box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
  80. }
  81. a:link, a:visited {
  82. color: #38488f;
  83. text-decoration: none;
  84. }
  85. @media (max-width: 700px) {
  86. div {
  87. margin: 0 auto;
  88. width: auto;
  89. }
  90. }
  91. </style>
  92. </head>
  93. <body>
  94. <div>
  95. <h1>Example Domain</h1>
  96. <p>This domain is for use in illustrative examples in documents. You may use this
  97. domain in literature without prior coordination or asking for permission.</p>
  98. <p><a href="https://www.iana.org/domains/example">More information...</a></p>
  99. </div>
  100. </body>
  101. </html>
  102. Si maintenant vous allez sur ``https://example.com`` avec un navigateur Web, et cliquez sur
  103. "Afficher le code source de la page", vous devriez voir exactement le contenu ci-dessus.
  104. Cela prouve que:
  105. * Il y a un serveur qui écoute sur l'adresse IP de example.com, sur le port 80
  106. * Ce serveur comprend le protocole HTTP
  107. * Un navigateur ne fait rien d'autre que:
  108. * envoyer des requêtes HTTP vers un serveur
  109. * interpréter le texte retourné et l'afficher
  110. * On peut facilement coder à la fois des *clients* et des *serveur* HTTP en Python, juste avec le module socket.