socklib.bbc
socklib.bbc
DESCRIPTION.
Le module socklib.bbc propose des procédures et des fonctions permettant d'établir des connexions socket avec un ordinateur distant via un réseau local ou Internet, et de transférer des données dans les deux sens.
SYNTAXE.
INSTALL @lib$ + "socklib.bbc"
REMARQUES.
Voici une présentation rapide pour comprendre et utiliser te module socklib.bbc, destinée aux néophytes en réseau.
Consultez l'un des nombreux sites traitant de la gestion des réseaux pour plus de détails.
1. Présentation d'un réseau.
Un réseau permet à plusieurs machines de communiquer en utilisant un certain nombre de règles communes, regroupées dans la définition d'un protocole, comme TCP/IP.
Quand 2 machines communiquent, il y a un serveur qui attend les connexions et un client qui se connecte au serveur. Les données échangées entre le serveur et le client passent par un canal de communication via une une interface de communication : un socket. Un socket est un point d’entrée/sortie logiciel permettant à un programme de communiquer avec un autre programme via un réseau.
Chaque machine connectée à un réseau reçoit une adresse IP, et chaque programme exécuté sur cette machine qui utilise cette connexion le fera en passant par un port, c'est-à-dire une entrée/sortie, qui lui sera dédié. Les valeurs :
- de 0 à 1023 sont réservées pour le système (OS) ;
- de 1024 à 49151 sont libre pour les autres applications ;
- de 49152 à 65535 seront utilisées comme ports temporaires par le système.
Une adresse locale, est une adresse IP d'une machine se trouvant dans un réseau privé, par exemple chez un particulier, une école ou une entreprise. Sa forme générale est xxx.xxx.xxx.xxx. Les adresses locales ne fonctionnent pas pour le réseau internet, elles sont uniquement reconnues sur un réseau local. Pour connaitre l'adresse IP local d'une machine tapez, dans un terminal, la commande ip a, sous Linux (ou ipconfig, sous windows de Microsoft), l'adresse réseau (local) IP de cette machine est indiquée dans la section 2 : eth0: inet xxx.xxx.xxx.xxx.
Il existe, bien évidement, des moyens de détecter, et de retourner, une adresse IP locale ou distante pour des connexions automatiques entre serveur et client, mais ces méthodes méthodes dépassent largement les objectifs de cette présentation.
2. Initialisation et finalisation, 2 étapes obligatoires.
Avant toute chose, il faut initialiser le module socklib.bbc avec la procédure PROC_initsockets, c'est comme si on allumait le réseau.
Et de même, et c'est même plus important, il faudra s'assurer de la bonne finalisation des communication, avant de fermer le programme, avec la procédure PROC_exitsockets, c'est comme si on éteint le réseau.
3. Créer un serveur : la machine qui attend.
Tout réseau doit avoir au-moins un serveur pour sa création, pour cela, Il faut ouvrir un port pour la ou les machines qui serviront de serveur du réseau avec l'appel de la fonction FN_tcplisten() qui va retourner un valeur qui identifiera cette machine comme étant le serveur. Par exemple : kserveur = FN_tcplisten( "" , "1234" ) va créer un serveur, où :
- kserveur , est l'identifiant du serveur ;
- "", écoute, accepte, toutes les connexions provenant de ce réseau (par Wi-Fi, Ethernet, loopback , ...) ;
- "1234", le numéro du port depuis lequel il écoute, attend, les connexions.
Plusieurs machines d'un même réseau peuvent servir de serveur, avec le même numéro de port, car chaque machine à sa propre adresse IP, et ce qui est pris en compte par le réseau c'est la combinaison adresse IP + port. Et donc de même, une machine peut avoir 2 identifiants de serveur, si ces 2 identifiants ont des numéros de ports différents. Par contre une machine ne peut pas ouvrir une deuxième fois le même port par un appel de la fonction FN_tcplisten().
4. Créer un client : la machine qui se connecte au serveur.
Pour créer des clients, c'est-à-dire des machines qui vont se connecter au serveur, on utilisera, pour chaque machine, un appel de la fonction FN_tcpconnect(). Cette appel de la fonction FN_tcpconnect() retournera une valeur numérique qui servira d'identifiant pour le client dans le réseau. Par exemple : kclient = FN_tcpconnect( "xxx.xxx.xxx.xxx" , "1234" ) va créer un client, où :
- kclient , est l'identifiant du client ;
- "xxx.xxx.xxx.xxx" , est l'adresse IP du serveur ;
- "1234", le numéro du port depuis lequel le serveur écoute les connexions.
5. Attendre une connexion.
Un fois qu'un serveur est créé, on le placera en attende de connexion (standby) en plaçant un appel de la fonction FN_check_connection() dans une boucle, dans laquelle un test logique IF ... THEN appellera une procédure personnalisée si un client se connecte au serveur. La fonction FN_check_connection() retournera une valeur numérique identifiant le client qui a sollicité le serveur. Par exemple :
REPEAT
kclient = FN_check_connection( kserveur )
IF kclient THEN PROC_Connesion( kclient )
WAIT( 10 )
UNTIL 1 = 0
END
DEF PROC_Connesion( Q ) : PRINT "Client connecté !"; Q : ENDPROC
6. Envoyer une chaine de caractères.
Pour envoyer une chaine de caractères du serveur vers un client, ou d'un client vers le serveur, on utilisera la fonction FN_writelinesocket(). Cette fonction prend 2 paramètres : l'identifiant du client, retournée par la fonction FN_check_connection() pour le serveur ou par la fonction FN_tcpconnect(), pour le client et la chaine de caractères à transmettre. Si la chaine de caractères est bien transmise, la fonction FN_writelinesocket() retourne 0. Par exemple : kenvoi = FN_writelinesocket( kclient , "Bonjour !" ) va envoyer la chaine de caractères Bonjour ! :
- depuis le serveur vers le client identifié par la valeur retournée par FN_check_connection() ;
- depuis le client, en s'identifiant avec la valeur retournée par FN_tcpconnect() vers le serveur.
7. Recevoir une chaine de caractères.
Pour attendre la réception d'une chaine de caractères du serveur vers un client, ou d'un client vers le serveur, on utilisera la fonction FN_readlinesocket(). Cette fonction prend 3 paramètres : l'identifiant du client, retournée par la fonction FN_check_connection() pour le serveur ou par la fonction FN_tcpconnect(), pour le client ; un délai d'attente maximal en centisecondes (100 correspond à une seconde) et l'identifiant de la variable existante dans la quelle la chaine de caractères sera stockée. Si la chaine de caractères est bien transmise, la fonction FN_readlinesocket() retourne sa longueur. sinon -1. Par exemple : krecue = FN_readlinesocket( kclient , 100 , kchaine$ ) va stocker dans kchaine$ la chaine de caractères envoyée de kchaine$ :
- depuis le serveur vers le client identifié par la valeur retournée par FN_check_connection() ;
- depuis le client, en s'identifiant avec la valeur retournée par FN_tcpconnect() vers le serveur.
8. Fermer une connexion serveur - client.
Il est important de fermer toutes les connexions qui n'ont plus d'utilité. Une fois les opérations d'envoi / reception entre le serveur et le client terminées, il est vivement conseillé de fermer le socket, le canal de communication, établi entre eux. Pour cela, on utilisera la procédure PROC_closesocket() du coté client. Normalement le serveur coupera le socket dès que le client se déconnectera, mais on peut, par prudence utiliser cette procédure depuis le serveur, en précisant bien l'identifiant du client, retourné par la fonction FN_check_connection().
9. Exemple simplifié d'une connexion serveur - client.
REM --- Cote serveur ---
REM --- Module de la bibliothèque BBC BASIC ---
INSTALL @lib$ + "socklib.bbc"
REM --- INITIALISATION GENERALE ---
ON CLOSE PROC_Fermeture
REM --- Initialisation de socklib ---
PROC_initsockets
REM --- Creation du serveur ---
kserveur = FN_tcplisten( "" , "1234" )
REM --- Mise en attende d'une sollicitation du client ---
PRINT "Serveur en attente sur le port 1234..."
REPEAT
kclient = FN_check_connection( kserveur )
UNTIL kclient <> 0
PRINT "Client connecté !"
REM --- Reception du client (timeout 10 secondes) ---
krecu$ = ""
REPEAT
krecu = FN_readlinesocket( kclient , 1000 , krecu$ )
IF krecu > 0 THEN
PRINT "Demande client : " + krecu$
ELSE
PRINT "Demande client non recue."
ENDIF
UNTIL krecu < 0
REM --- Envoi d'une reponce par le serveur ---
IF krecu > 0 THEN
kenvoi$ = krecu$ + " : bien recu."
FN_writelinesocket( kclient , kenvoi$ )
ENDIF
REM --- Fermeture du canal de communication (socket) ---
PRINT "Client déconnecte."
PROC_closesocket( kclient )
REM --- Fermeture du reseau ---
PRINT "Reseau ferme."
PROC_Fermeture
END
REM --- Gestion de la fermeture du programme ---
DEF PROC_Fermeture
PROC_exitsockets
QUIT
ENDPROC
REM --- Cote client ---
REM --- Module de la bibliothèque BBC BASIC ---
INSTALL @lib$ + "socklib.bbc"
REM --- INITIALISATION GENERALE ---
ON CLOSE PROC_Fermeture
REM --- Initialisation de socklib ---
PROC_initsockets
REM --- Creation du client ---
INPUT "IP du serveur, svp : " ; kserveur$
kclient = FN_tcpconnect( kserveur , "1234" )
IF kchaine$ < 1 THEN PROC_Fermeture
PRINT "Connexion etalie."
REM --- Envoi d'une requete au serveur ---
kchaine$ = "Bonjour serveur ..."
FN_writelinesocket( kclient , kchaine$ )
REM --- Attente du recepisse du serveur ---
krecus = FN_readlinesocket( kclient , 1000 , krecu$ )
IFkrecus > 0 THEN
PRINT krecu$
ELSE
PRINT "Pas de reponse"
ENDIF
REM --- Fermeture du canal de communication (socket) ---
PRINT "Déconnection du client."
PROC_closesocket( kclient )
PROC_Fermeture
END
REM --- Gestion de la fermeture du programme ---
DEF PROC_Fermeture
PROC_exitsockets
QUIT
ENDPROC
Pour plus de détails, sur l'établissement d'un réseau local avec le module socklib.bbc, vous pouvez étudier attentivement les exemples créés par R.T. RUSSELL : server,bbc, server_multi.bbc et client.bbc fournis dans le répertoire examples/general/ de votre distribution BBC BASIC for SDL 2.0.
Le module doit être chargé depuis votre programme à l'aide de l'instruction : INSTALL @lib$ + "socklib.bbc"
LISTE DES PROCEDURES DU MODULE.
FN_check_connection() : vérifie, sur un serveur, si un client se connecte.
FN_check_connectionM() : idem FN_checkconnection(), mais sans fermer le socket d'écoute.
FN_gethostname : retourne le nom de la machine sur le réseau.
FN_getpeername() : retourne une chaine de caractère avec l'adresse IP de la machine distante connectée.
FN_readlinesocket() : réceptionne une chaine de caractères.
FN_readsocket() : réceptionne un certain nombre d'octets et les écrit en mémoire.
FN_recvfromsocket() : réceptionne une suite d'octets via une connexion UDP.
FN_sendtosocket() : envoie une suite d'octets via une connexion UDP.
FN_sethost() : retourne l'adresse IP d'une machine en ordre d'octets réseau.
FN_setport() : retourne le numéro de port en ordre d'octets réseau.
FN_socketerror : retourne le code numérique de la dernière erreur de socket.
FN_socketerror$ : retourne une chaine de caractères décrivant la dernière erreur de socket.
FN_tcpconnect() : établit une connexion TCP/IP, désignant la machine comme client du réseau.
FN_tcplisten() : établit une connexion TCP/IP, désignant la machine comme serveur du réseau.
FN_udpsocket() : établit une connexion UDP et peut éventuellement se lier à l'hote.
FN_writelinesocket() : envoie une chaine de caractères suivi d'un retour chariot et d'un saut de ligne.
FN_writesocket() : envoie une suite d'octets débutant à une certaine adresse mémoire.
PROC_closesocket() : ferme un socket.
PROC_exitsockets : ferme les connexions.
PROC_initsockets() : initialise les connexions.
Votre aide est précieuse pour améliorer ce site, alors n'hésitez pas à faire part de
Dans la RETROGICIEL vous trouvez des suggestions simples et classiques pour
TESTER - DÉCOUVRIR - PRATIQUER - APPROFONDIR - EXPLORER
avec un exemple de résolution à télécharger pour vous inspirer.