piper a écrit : ↑mar. 31 août 2021 08:51
...
Ce code ne devrait fonctionner que si le code serveur et le code client ne s'exécutent sur la même machine non ?
Non, pas nécessairement. A partir du moment ou un socket TCP/IP à un n° de port d’attribué (bind) et que l’on lui dit d’écouter (listen) il peut accepter toutes les connexions qu’elles soient locale ou distante (si toutes règle d’éventuels routages et firewall l’autorise bien entendu). Si on veut restreindre l’accès a un serveur uniquement a des demandes locales, alors on définit l’ip du socket serveur avec une adresse de bouclage (utile en phase de développement surtout si l’on a des contraintes de sécurité)
Au plus simple, voilà sommairement comment fonctionne une connexion client/serveur en mode TCP/IP :
Dans les 2 cas on commence par initialiser un socket en lui définissant la famille d’adressage, et le protocole. Ici dans les 2 cas on a comme paramètres AF_INET qui correspond au type d’adressage Internet (IP v4) et SOCK_STREAM qui correspond au mode du protocole (TCP).
Ensuite on définit le point de terminaison du socket. Un point de terminaison, c‘est une adresse et un n° de port.
Pour un serveur : on doit impérativement lui assigner un n° Port (ici 50000). Pour l’IP, c’est différent dans le sens ou le système peut avoir plusieurs interface réseau ou même plusieurs adresses sur une même interface. Donc soit-on défini une de ces adresses ou alors on laisse par défaut, ce qui correspond en IPv4 ‘0.0.0.0’ soit toutes les adresses de toutes les interfaces. Ce dernier cas peut par exemple être utile si vous avez développer un serveur sur un PI et vous voulez pouvoir y accéder aussi bien en ciblant l’IP Ethernet ou l’ip WIFI. L’attachement du point de terminaison au socket se fait dans la plupart des langage par une instruction bind(ip,port). Comme c’est un serveur, on doit le mettre à l’écoute des connexions entrantes. Ça, c’est le rôle de la fonction listen().
Pour un client : Dans l’absolu et la majorité des cas, on laisse par défaut l'ip et le port par défaut ‘0.0.0.0’,0 (toutes les adresses de toutes les interface et n° de port dynamique). De ce fait, avec beaucoup de langage et librairie socket, pas besoin d’instruction bind pour définir le point de terminaison. Si vraiment on a besoin d’un port fixe ou que l’on veut impérativement utiliser une ip précise, alors on le défini comme pour un serveur. Par contre, pas d’instruction listen pour un client puisqu’il n’est pas sensé être à l’écoute de connexion autre que celle qu’il lui-même demandé.
On a donc un serveur qui est à l’écoute de demande de connexion TCP/IP sur le port 50000 d’une ou de toutes les IP du système. Le client s’attribue un n° de port automatiquement (cas par défaut avec port 0) et envois une demande de connexion en direction de (d’une) l’adresse du serveur sur le n° de port 50000. L’ip et le n° port du client sont contenu dans les trames réseaux sous forme d’une structure bien définie appelée NPDU (Network Protocol Data Unit). Quand un serveur TCP/IP reçoit une demande de connexion ou des données d’un client, ils identifie le client en trouvant son ip et son n° de port (et bien d’autres chose) dans cette structure. C’est ce qui permet à un serveur de dialoguer avec une multitude de client en renvoyant les bonnes données à chaque client.
Les p’tit + pour les débutants en réseaux IP
Il faut voir le socket comme une interface entre le soft et le hard réseaux.
Si vous vous lancez dans le développement d’un petit serveur TCP/IP, vous pouvez tester les connexions sans avoir besoin de développer tout de suite un client. Vous pouvez pour ça utiliser un simple terminal telnet. A noter que je vous recommande vivement de boycotter Python pour tout ce qui est serveur réseaux. Si vous etes débutant, tournez vous plutôt vers NodeJs pour ca.
Les sockets sont une très bonne solution aussi si l’on a besoin de faire dialoguer ensemble plusieurs programmes qui tourne sur un même système. L’énorme avantage d’un socket ip est qu’il permet de dialoguer aussi bien entre des programmes locaux que distant et contrairement aux com+ , named pipe ou socket unix, ils sont multi-plateforme et travaillent de la même façon sur tous les système. Attention toutefois de ne pas en abusé. Le nombre de port est limité (il y a de la marge quand meme)
Attention avec les codes serveur comme celui de Melchior59. Le programme est bloqué en attente de connexion dans le thread principale, ce qui veut que le programme ne peut rien faire d’autre en même temps et tous les traitements doivent être fait dans l’annexe de la boucle while. Pour un tout petit programme qui ne va traiter qu’un seul client à la fois et qui ne fait pas grand-chose, ça peut suffire, mais pas au-delà.