Les sockets réseaux avec LiveCode
Il existe deux types de communication :
Le mode connecté utilisant le protocole TCP. Ce mode de connexion est comparable à une communication téléphonique. Une connexion durable s'établit entre l'émetteur (client) et le récepteur (serveur). L'adresse de destination est nécessaire seulement à l'initialisation de la connexion.
Le mode non connecté utilisant le protocole UDP. Ce mode de connexion est comparable à l'envoi d'un courrier et n'exige aucun accusé de réception. L'adresse de destination est obligatoire à chaque connexion.
Création de notre premier serveur UDP
Pour réaliser notre serveur UDP, nous utiliserons une machine virtuelle sous Linux. Celui-ci aura pour adresse IP 172.16.209.176. Nous aurons besoin d'une pile contenant un bouton nommé "Start" et c'est tout. Nommez de suite votre pile UDP Serveur.
Cliquez droit sur le bouton pour obtenir l'inspecteur d'objet. Saisir Start dans Name et Label. Ensuite cliquez droit une nouvelle fois sur le bouton pour ouvrir une fenêtre de l'éditeur de code. Tout d'abord, nous saisirons le code associé au bouton Start.
on mouseUp
   -- on vérifie le label du bouton
   -- start : démarrage du serveur
   -- stop : arret du serveur
   if the label of me = "Start" then
      -- on accepte les connexions UDP sur le port 9997
      -- la procédure dataReceived est initialisée
      accept datagram connections on port 9997 with message "dataReceived"
      -- on modifie le label du bouton à stop
      set the label of me to "Stop"
   else
      -- la connexion UDP est arreté
      close socket 9997
      -- on modifie le label du bouton à start
      set the label of me to "Start"
   end if
end mouseUp
Explication : On accepte les connexions UDP entrantes sur le port 9997. Pour chaque connexion réussie, on exécutera la procédure (Message Handler) dataReceived.
Il faut créer le reste du code.
on dataReceived pSocket, pMsg
   -- affichage boite de dialogue message UDP recu
   answer pSocket & cr & pMsg
end dataReceived
Explication : Le serveur reçoit la trame UDP et la traite par cette procédure. On récupère l'adresse de la machine distante et le message.
on socketError
   -- affichage boite de dialogue erreur flux UDP
   answer "Failed to open server socket"
end socketError
Explication : la procédure socketError est activée lorsqu'un problème survient lors de l'établissement de la connexion UDP.
on mouseUp
   -- on vérifie le label du bouton
   -- start : démarrage du serveur
   -- stop : arret du serveur
   if the label of me = "Start" then
      -- on accepte les connexions UDP sur le port 9997
      -- la procédure dataReceived est initialisée
      accept datagram connections on port 9997 with message "dataReceived"
      -- on modifie le label du bouton à stop
      set the label of me to "Stop"
   else
      -- la connexion UDP est arreté
      close socket 9997
      -- on modifie le label du bouton à start
      set the label of me to "Start"
   end if
end mouseUp
Explication : On accepte les connexions UDP entrantes sur le port 9997. Pour chaque connexion réussie, on exécutera la procédure (Message Handler) dataReceived.
Il faut créer le reste du code.
on dataReceived pSocket, pMsg
   -- affichage boite de dialogue message UDP recu
   answer pSocket & cr & pMsg
end dataReceived
Explication : Le serveur reçoit la trame UDP et la traite par cette procédure. On récupère l'adresse de la machine distante et le message.
on socketError
   -- affichage boite de dialogue erreur flux UDP
   answer "Failed to open server socket"
end socketError
Explication : la procédure socketError est activée lorsqu'un problème survient lors de l'établissement de la connexion UDP.
Création du programme client UDP
Le programme client va être réalisé dans un environnement Mac. Nous avons besoin d'une pile contenant deux champs texte "txtMessage" et "ipDestination" et d'un bouton nommé "Send". Nommez votre projet UDP client.
Cliquez sur le bouton Send servira à initialiser la connexion TCP. Voici le code.
on mouseUp
   -- vérification d'un message
   if fld "txtMessage" is not empty then
      local ipDest
      -- initialisation de la variable ipDest
      -- ipDest adresse de destination du serveur UDP accompagné du numéro de port
      put fld "ipDestination" into ipDest
      put ":9997" after ipDest
      -- ouvre un flux UDP
      open datagram socket to ipDest
      if the result is not empty then
         -- pb réseau on envoie le résultat
         answer "Socket: " & the result
      end if
      -- on envoie le message sans accusé de reception
      write fld "txtMessage" to socket ipDest
      -- on clot la connexion UDP
      close socket ipDest
      -- on efface le message
      put empty into fld "txtMessage"
   else
      beep
   end if
end mouseUp
Explication : on vérifie l'existence d'un message dans le champ texte, puis on crée la connexion UDP et on envoie directement le message sur le port 9997. on clos la communication puisqu'on n'attends pas d'accusé de réception du serveur. A la fin, on efface le message.
on socketError
   answer "Failed to open socket"
end socketError
Comme précédemment, cette procédure intercepte les erreurs du flux TCP
on mouseUp
   -- vérification d'un message
   if fld "txtMessage" is not empty then
      local ipDest
      -- initialisation de la variable ipDest
      -- ipDest adresse de destination du serveur UDP accompagné du numéro de port
      put fld "ipDestination" into ipDest
      put ":9997" after ipDest
      -- ouvre un flux UDP
      open datagram socket to ipDest
      if the result is not empty then
         -- pb réseau on envoie le résultat
         answer "Socket: " & the result
      end if
      -- on envoie le message sans accusé de reception
      write fld "txtMessage" to socket ipDest
      -- on clot la connexion UDP
      close socket ipDest
      -- on efface le message
      put empty into fld "txtMessage"
   else
      beep
   end if
end mouseUp
Explication : on vérifie l'existence d'un message dans le champ texte, puis on crée la connexion UDP et on envoie directement le message sur le port 9997. on clos la communication puisqu'on n'attends pas d'accusé de réception du serveur. A la fin, on efface le message.
on socketError
   answer "Failed to open socket"
end socketError
Comme précédemment, cette procédure intercepte les erreurs du flux TCP
Fonctionnement
Il faut démarrer notre serveur UDP sur Linux en cliquant sur le bouton Start. Afin de vérifier son bon fonctionnement, utilisez la commande netstat -an | grep 9997 en ligne de commande.
Ensuite, saisissez un message dans le programme UDP client et cliquez sur le bouton send. Une boîte de dialogue doit s'afficher sur le poste Linux.
Création de notre premier serveur TCP
Une fois n'est pas coutume, nous utiliserons une machine sous Windows pour réaliser notre premier serveur. Celui-ci aura pour adresse IP 172.16.209.176. Nous aurons besoin d'une pile contenant un bouton et une liste appelée LstMessage. Nommez de suite notre pile Socket Serveur.
Cliquez droit sur le bouton pour ouvrir une fenêtre de l'éditeur de code. Tout d'abord, nous saisirons le code associé au bouton Démarrage Serveur.
on mouseUp
   accept connections on port 20001 with message "MachineConnecte"
end mouseUp
Explication : On accepte les connexions TCP entrantes sur le port 20001. Pour chaque connexion réussie, on exécutera la procédure (Message Handler) MachineConnecte.
Il faut créer le reste du code.
on MachineConnecte ipMachine
   read from socket ipMachine until return with message "nouveauMessage"
end MachineConnecte
Explication : La connexion est établie, on initialise la procédure nouveauMessage. Le flux TCP utilisera cette procédure tant que la connexion est active.
on nouveauMessage ipMachine theMessage
   put ipMachine && ":" && theMessage & return after field "LstMessage"
   read from socket ipMachine until return with message "nouveauMessage"
end nouveauMessage
Explication : les données du client sont récupérées par la procédure nouveauMessage. On récupère l'adresse IP et le message dans la liste LstMessage. Chaque message est délimité par un retour chariot. La dernière ligne permet de traiter les messages suivants.
on mouseUp
   accept connections on port 20001 with message "MachineConnecte"
end mouseUp
Explication : On accepte les connexions TCP entrantes sur le port 20001. Pour chaque connexion réussie, on exécutera la procédure (Message Handler) MachineConnecte.
Il faut créer le reste du code.
on MachineConnecte ipMachine
   read from socket ipMachine until return with message "nouveauMessage"
end MachineConnecte
Explication : La connexion est établie, on initialise la procédure nouveauMessage. Le flux TCP utilisera cette procédure tant que la connexion est active.
on nouveauMessage ipMachine theMessage
   put ipMachine && ":" && theMessage & return after field "LstMessage"
   read from socket ipMachine until return with message "nouveauMessage"
end nouveauMessage
Explication : les données du client sont récupérées par la procédure nouveauMessage. On récupère l'adresse IP et le message dans la liste LstMessage. Chaque message est délimité par un retour chariot. La dernière ligne permet de traiter les messages suivants.
Création de notre programme client TCP
Le programme client va être réalisé dans un environnement Mac. Nous avons besoin d'une pile contenant deux boutons et une liste. Nommez notre projet Socket client.
Bouton connexion
Ce bouton servira à initialiser la connexion TCP. Voici le code.
on mouseUp
   open socket to "172.16.209.176:20001"
   if the Result <> "" then
      put "result:" && the result
   end if
end mouseUp
Explication : la commande open socket tente l'ouverture d'une connexion TCP avec le port 20001 et l'adresse du serveur 172.16.209.176. Si la connexion est déjà active, on affiche le résultat dans la fenêtre MessageBox.
on mouseUp
   open socket to "172.16.209.176:20001"
   if the Result <> "" then
      put "result:" && the result
   end if
end mouseUp
Explication : la commande open socket tente l'ouverture d'une connexion TCP avec le port 20001 et l'adresse du serveur 172.16.209.176. Si la connexion est déjà active, on affiche le résultat dans la fenêtre MessageBox.
Bouton envoi
Ce bouton servira à envoyer le message stocké dans la liste LstMessage. Voici le code.
on mouseUp
   write field "LstMessage" & return to socket "172.16.209.176:20001"
end mouseUp
Explication : le contenu de LstMessage est envoyé vers le serveur 172.16.209.176 avec le port 20001.
on mouseUp
   write field "LstMessage" & return to socket "172.16.209.176:20001"
end mouseUp
Explication : le contenu de LstMessage est envoyé vers le serveur 172.16.209.176 avec le port 20001.
Fonctionnement
Il faut démarrer notre serveur en cliquant sur le bouton Démarrage Serveur. Afin de vérifier son bon fonctionnement, utilisez la commande netstat -an en ligne de commande.
Ensuite, cliquez sur le bouton connexion du client. Un point d'arrêt dans la procédure MachineConnecte nous indique l'établissement de la connexion.
Nous pouvons vérifier la connexion TCP côté serveur :
>netstat -an | grep 20001
TCP 172.16.209.176:20001 172.16.209.1:51545 Établie
et côté client :
>netstat -an | grep 20001
tcp4 0 0 172.16.209.1.51545 172.16.209.176.20001 ESTABLISHED
Continuons en envoyant un texte au serveur. Côté client, nous saisissons "essai de message" et cliquons sur le bouton envoyer.
>netstat -an | grep 20001
TCP 172.16.209.176:20001 172.16.209.1:51545 Établie
et côté client :
>netstat -an | grep 20001
tcp4 0 0 172.16.209.1.51545 172.16.209.176.20001 ESTABLISHED
Continuons en envoyant un texte au serveur. Côté client, nous saisissons "essai de message" et cliquons sur le bouton envoyer.
Vous avez vu un bref aperçu de ce que l'on peut faire avec Livecode et les sockets BSD. N'hésitez pas à améliorer ces petits programmes. A vos claviers !
J'ai rajouté un article sur le cryptage des données UDP que vous trouverez ici
J'ai rajouté un article sur le cryptage des données UDP que vous trouverez ici