Interconnexions REBOL / DELPHI via TCP/IP




  • Objectif :

  • Le but de cet article est de vous faire découvrir, comment, via un port TCP d’un serveur TCP/IP, nous pouvons faire communiquer deux programmes développés dans des langages distincts.

    Dans un premier temps je vous invite à développer les fonctionnalités d’un programme d’écoute du port 8500 (port libre ) d’un serveur TCP/IP. L’implémentation de ce programme se fera en DELPHI 5 et il s'agit d'un service qui tournera sous Windows NT ou 2000 Server

    Nous développerons, ensuite en REBOL, un programme qui envoi un message via un port TCP à ce service.



  • Le programme en DELPHI 5 (côté Serveur)

  • A l’exécution du code présenté ci-après : le serveur se met en écoute et dès réception d'un message du client, le message " Message Reçu : <message envoyé par le client>" est retourné au client.

    Le programme principal nommé ServiceNT est sauvegardé sous ServiceNT.dpr. Il utilise l'unité EssaiService sauvegardée sous EssaiService.pas.
    Program ServiceNT;
    
    Uses 
       svcmgr, 
       EssaiService in 'EssaiService.pas' {Service1: 
    TService}; 
    
    {$R *.RES} 
    
    begin 
       Application.Initialize; 
       Application.Title := 'ServerSocket'; 
       Application.CreateForm(TService1, Service1); 
       Application.Run; 
    End. 
    


    Notre unité EssaiService (EssaiService.pas) est construite de la manière suivante :
    unit EssaiService; 
    
    interface 
    
    uses 
       Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ScktComp;
    
    TService1 = class(TService)
       ServerSocket1: TServerSocket;
       procedure ServiceStart(Sender: TService; var Started: Boolean); 
       procedure ServiceShutdown(Sender: TService); 
       procedure ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
       procedure ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
       Private 
          { Déclarations privées } 
       Public
          { Déclarations publiques }
          function GetServiceController: TServiceController; override;
    end;
    
    var 
       Service1: TService1;
       port: TCustomWinSocket;
    
    implementation
    
    {$R *.DFM}
    
    {******************************************************************************}
    procedure ServiceController(CtrlCode: DWord); stdcall;
    begin
       Service1.Controller(CtrlCode);
    end;
    
    {******************************************************************************}
    function TService1.GetServiceController: TServiceController;
    begin
       Result := ServiceController;
    end;
    
    {******************************************************************************}
    {Sur Démarrage du Service}
    procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
    begin
       ServerSocket1.Active:=False;
       ServerSocket1.Port:=8500;
       ServerSocket1.Active:=True;
       Started:=True;
    end;
    
    {******************************************************************************}
    {Sur Arrêt du service}
    procedure TService1.ServiceShutdown(Sender: TService);
    begin
       ServerSocket1.Active:=False;
    end;
    
    {******************************************************************************}
    {Sur Connection du client.}
    procedure TService1.ServerSocket1ClientConnect(Sender: TObject;
       Socket: TCustomWinSocket);
    begin
       {Affectation du port client}
       port:=Socket;
    end;
    
    {******************************************************************************}
    {Sur lecture du Client}
    procedure TService1.ServerSocket1ClientRead(Sender: TObject;
       Socket: TCustomWinSocket);
    var
       strReceiveText: String;
    begin
       Socket:=port;
       strReceiveText:=Socket.ReceiveText;
    if (Length(Trim(strReceiveText))<>0) then
       begin
          {envoi de texte vers le port client}
          port.SendText('Message Reçu : '+strReceiveText);
          {Fermeture du port client}
          port.close;
       end;
    end;
    {******************************************************************************}
    end.
    


    N'oublions pas d'initialiser les propriétés des objets Tservice et TserverSocket définis dans le fichier EssaiService.dfm :
    
    
    Object Service1: TService1   
       OldCreateOrder = False   
       DisplayName = 'Essai d''un Service NT (Ecoute du port 8500)'   
       StartType = stManual   
       OnShutdown = ServiceShutdown   
       OnStart = ServiceStart   
       Left = 189   
       Top = 104   
       Height = 375   
       Width = 544   
       Object ServerSocket1: TserverSocket
          Active = False   
          Port = 8500   
          Service = 'testBenoit'   
          ServerType = stNonBlocking   
          OnClientConnect = ServerSocket1ClientConnect   
          OnClientRead = ServerSocket1ClientRead   
          Left = 32   
          Top = 16   
       End   
    End
    
    
    
    

    La propriété Service de l'objet TserverSocket est initialisée à 'testBenoit'. Cette dernière revêt une importance capitale pour la suite. En effet, c’est ce nom qui doit figurer dans le fichier services de Windows NT.

    Il nous reste maintenant quatre étapes avant le démarrage du service:

    1. Compiler ServiceNT
    2. Copier le fichier ServiceNT.exe sur le serveur.
    3. Modification du fichier services sous le répertoire System32. Il s'agit ici de répertorier notre nouveau service testBenoit. Pour cela, Il suffit d'ajouter au fichier services existant la ligne suivante :
      testBenoit     8500/tcp
    4. Voici un extrait du fichier services de la machine hôte:
      # Copyright (c) 1993-1995 Microsoft Corp.
      #
      # This file contains port numbers for well-known services as defined by
      # RFC 1060 (Assigned Numbers).
      #
      # Format:
      #
      # <service name>  <port number>/<protocol>  [aliases...]   [#<comment>]
      #
      
      echo             7/tcp
      echo             7/udp
      discard          9/tcp    sink null
      discard          9/udp    sink null
      systat           11/tcp
      systat           11/tcp    users
      daytime          13/tcp
      daytime          13/udp
      netstat          15/tcp
      
      testBenoit     8500/tcp
      
    5. Afin d'installer le service dans la liste des services, saisir la ligne de commande suivante :
      <chemin du fichier ServiceNT.exe> /INSTALL

    Si tout s'est bien déroulé il ne vous reste plus qu'à démarrer le service.

    Par la suite, si vous désirez désinstaller ce service, il vous suffira de l'arrêter et de saisir la ligne de commande suivante :
    <chemin du fichier ServiceNT.exe> /UNINSTALL



  • Le programme en REBOL/CORE (côté Client)
  • Le programme en REBOL permet tout d’abord

    Vous aurez remarqué, d’une part, la facilité avec laquelle REBOL effectue les tâches de lectures/ écritures via un port TCP et d’autre part le nombre de lignes de codes nécessaires !



  • Conclusion :

  • Nous pouvons imaginer un nombre incalculable d’applications basées sur ce modèle.
    Des clients Rebol peuvent ainsi venir se connecter à une machine distante via un socket et obtenir un service particulier tel que l’accès à une base de données, à un annuaire LDAP ou au gestionnaire d’impression. C’est la base du distributing Computing.

    A vous d’essayer !

    Benoit Delannoy

    Retour