[F# et Shell] Un peu de réseau

Un petit exemple de programmation réseau, en F# et en Shell.

F#

Je viens d'écrire un petit programme en F#, je le poste ici puisqu'il pourra me resservir plus tard, et il peut être utile à d'autres personnes.

Le code est assez court, il s'agit d'un serveur (en TCP). Lorsqu'un client se connecte, il communique avec : le client envoie un nombre, le serveur renvoie ce nombre, mis au carré. C'est donc très simple, mais ça me fait une base pour une application réseau. Le programme permet d'accepter plusieurs clients ; j'utilise un thread par client.

Le code total tient en 25 lignes, ce qui me semble plutôt raisonnable. Le code se trouve à cette adresse : http://laurent.le-brun.eu/fsharp-server.fs

Shell

Et puisque les gens sous-estiment très souvent la puissance du Shell (et des binaires souvent associés), voici un équivalent en Shell :

$ nc -lp 3000 -c 'sed -u "s/.*/&*&/" | bc'

Netcat (ou nc) est un client / serveur utilisable en console. Par défaut, il est en mode TCP. Le 3000 correspond au port à utiliser et l'option -c indique la commande à exécutée quand un client se connecte. L'entrée standard correspond alors au message envoyé par le client et la sortie standard est le texte renvoyé. Le Sed sert juste à dupliquer l'entrée et insère un '*'. Cela permet donc de calculer le carré, grâce à bc. L'option -u de Sed est très importante ici : cela permet de ne pas bufferiser la sortie.

Ce code n'est pas un équivalent fidèle du programme F# : il manque la gestion d'erreur (si l'entrée n'est pas un nombre, le résultat est incertain et dépend de bc), la gestion de plusieurs clients simultanés et il faudrait que le serveur reste actif quand le client se déconnecte (dans la version ci-dessus, le serveur se termine).

Voici une solution plus fidèle. Code à mettre dans le fichier server.sh (avec les droits d'exécution) :

#! /bin/bash
nc -lp 3000 -e server.sh &
sed -u "s/.*[^0-9].*/*/;s/.*/&*&/" | bc

Exemple d'appel, via le shell :

$ nc -lp 3000 -e server.sh

À chaque fois qu'un client se connecte, un nouveau serveur (un nouveau processus donc) est lancé qui sera à l'écoute des nouveaux clients. On a donc une récursion mutuelle entre nc et server.sh. Le code Sed a été légèrement modifié de sorte que bc renvoie une erreur dès que l'entrée n'est pas un nombre.