|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
![]() ![]() Inscription : juin 2006 Messages : 6 935 ![]() |
Bonjour,
Pour ce troisième défi, l'équipe de developpez.com a décidé de faire un challenge délicat à résoudre avec un langage purement fonctionnel, pour montrer que dans des cas particuliers, un langage impératif peut être efficace. Challenge Le but du challenge est de réaliser un mini-serveur. Le serveur utilisera le protocole TCP et attendra des demandes de connexions sur un port quelconque (par exemple 3000). Lorsqu'un client se connecte, il pourra envoyer plusieurs chaines au serveur :
Tant que le client ne se sera pas déconnecté, le serveur devra continuer à être en écoute pour ce client particulier (il est possible de définir un timeout dans le cas où le client n'envoie aucune donnée durant un certain temps). Le serveur devra pouvoir gérer simultanément plusieurs clients. Il est possible de tester cette application avec la commande :
Exemple Par exemple, si vous vous connectez avec socket localhost 3000. Voici un scénario de fonctionnement : Code :
Les règles Il n'y a pas de règle particulière (évidemment, il faut que la solution proposée fonctionne). Vous pouvez proposer des solutions aussi bien dans des langages fonctionnels (caml, haskell, scheme, lisp...) qu'impératif. Le public pourra ainsi juger du code suivant divers critères :
Le public pourra également juger les différences entre une solution fonctionnelle et une solution impérative. Il lui sera ainsi plus facile de voir, pour un même problème, les différences entre divers paradigmes. A vos claviers de votre participation.
__________________
Je ne répondrai à aucune question technique en privé |
||
|
|
00
|
|
|
#2 | |||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Citation:
Voilà une solution en Shell (testée sous Zsh et Bash). Elle n'est pas tout à fait parfaite, puisqu'elle ne gère qu'un seul client à la fois (le serveur se termine quand le client part). Mais la connexion reste active pour le client et il y a une gestion d'erreur (qui affiche en plus le numéro de la ligne erronée). Elle gère aussi les entiers de n'importe quelle taille. Code :
nc -lp 3000 -c 'sed -u "s/.*[^0-9].*/*/;s/.*/&*&/" | bc' Exemple d'utilisation (en gras, les réponses du serveur) : Code :
Promis, je proposerai une solution plus "classique". Mais un autre jour. |
|||
|
|
00
|
|
|
#3 | ||
|
Membre éclairé
![]() ![]() Inscription : août 2005 Messages : 417 ![]() |
anubis/library/examples/network/client_server.anubis:
(je n'ai pas changé un iota, ce qui fait que ce n'est pas exactement ce qui est demandé, mais presque) Code :
Pour l'exécuter, il faut une version 1.8. Vous en trouverez une ici pour Linux.
__________________
Ma page maths. |
||
|
|
00
|
|
|
#4 | |
|
Membre éclairé
![]() ![]() Inscription : août 2005 Messages : 417 ![]() |
Citation:
__________________
Ma page maths. |
|
|
|
00
|
|
|
#5 | |
![]() ![]() ![]() Nicolas ValléeIngénieur d'études Inscription : décembre 2005 Messages : 9 963 ![]() |
Citation:
|
|
|
|
00
|
|
|
#6 |
|
Membre éclairé
![]() ![]() Inscription : août 2005 Messages : 417 ![]() |
Heu ... La ligne de code shell proposée par LLB me fait swapper ma LinuxBox (Ubuntu Dapper Drake) que même la souris ne bouge plus (j'ai essayé deux fois).
__________________
Ma page maths. |
|
|
00
|
|
|
#7 | ||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
J'ai essayé sur plusieurs machines (Linux, FreeBSD), en local comme en réseau, et ça a bien marché. Sous FreeBSD, netcat n'avait pas l'option -c, j'ai dû utiliser l'option -e (et le gnu sed s'appelle gsed) :
Code :
|
||
|
|
00
|
|
|
#8 | ||||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Voilà, la gestion multi-clients est faite.
Je viens d'écrire cette version, avec une communication entre les processus via un tube nommé : Code :
... avant de me rendre compte qu'on peut faire bien plus simple, via une récursion mutuelle (server.sh et nc) : Code server.sh :
La première version a le mérite d'être plus verbeuse à l'exécution (côté serveur, j'affiche quand un client se connecte ou se déconnecte). La deuxième, bien plus courte, utilise un processus de moins (celui qui faisait le while true). |
||||
|
|
00
|
|
|
#9 | ||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Voilà maintenant une solution basique en F#.
C'est la première fois que j'utilise du réseau et des threads sous .NET. Je me suis donc inspiré de codes en C#. Pas grand-chose de particulier à dire, je crée un thread à chaque connexion. Code F# :
Pour reprendre ce que je disais, je ne pense pas qu'un langage à dominante impérative apporte vraiment, c'est surtout une question de bibliothèque. D'ailleurs, cette version en F# est plus concise que les codes C# que j'ai trouvés, quand bien même la bibliothèque réseau aurait été pensée en impératif. |
||
|
|
00
|
|
|
#10 | ||
![]() ![]() ![]() Nicolas ValléeIngénieur d'études Inscription : décembre 2005 Messages : 9 963 ![]() |
une petite version OCaml minimaliste...
Code ocaml :
|
||
|
|
00
|
|
|
#11 | ||
|
Membre Expert
![]() Inscription : avril 2007 Messages : 829 ![]() |
Minimaliste ? peut mieux faire
Code :
|
||
|
|
00
|
|
|
#12 | ||
![]() ![]() Inscription : juin 2006 Messages : 6 935 ![]() |
Voici la solution que j'avais fait, et je crois que niveau taille, je suis largement battu.
Source en java, il y a un timeout au cas où le client ne parle plus pendant 5 secondes. Ca gère plusieurs clients jusqu'à leur déconnexion (ou timeout). Code java :
__________________
Je ne répondrai à aucune question technique en privé |
||
|
|
00
|
|
|
#13 | ||
![]() ![]() Étudiant Inscription : février 2006 Messages : 1 076 ![]() |
Ah, enfin un défi pile dans le domaine d'application de Perl
Une solution simple pour commencer (mais qui a tout de même la particularité de créer un processus par client) : Code Perl :
Alors Jedai, qu'est ce qui ne vas pas ?
__________________
"En essayant continuellement, on finit par réussir. Donc : plus ça rate, plus on a de chances que ça marche" (devise Shadock) Application : ainsi qu'à regarder la avant de poser une question.La rubrique Perl recrute, contactez-moi. |
||
|
|
00
|
|
|
#14 | ||
|
Membre chevronné
![]() Inscription : mai 2005 Messages : 657 ![]() |
Une solution rapide en Ruby, qui ressemble étrangement à celle en Perl
Elle gère également plusieurs clients en parallèle. Code :
__________________
Toute la documentation Ruby on Rails : gotapi.com/rubyrails Mes articles : > HAML : langage de template pour Ruby on Rails |
||
|
|
00
|
|
|
#15 | |||
|
Expert Confirmé Sénior
![]() ![]() |
Citation:
Une petite solution en Haskell : Code :
-- Jedaï |
|||
|
|
00
|
|
|
#16 | ||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Autre solution en F#. La première était inspirée de code C#, celle-là est beaucoup plus typique de F#. Elle repose sur la programmation asynchrone (donc elle ne bloque pas les threads) et les monades. Contrairement à l'autre, elle ne crée par un thread par client et devrait être beaucoup plus légère.
Code :
|
||
|
|
00
|
|
|
#17 | ||
|
Membre du Club
![]() Inscription : octobre 2007 Messages : 34 ![]() |
Une solutioin en Erlang. Donc ça lance une thread par client, et je doit valider moi même l'entrée, la fonction standard de la librairie ne retournant pas assez d'information pour se baser dessus.
Code :
|
||
|
|
00
|
Copyright © 2000-2013 - www.developpez.com