Comment faire pour utiliser des canaux nommés dans un programme 32 bits de Visual Basic

Traductions disponibles Traductions disponibles
Numéro d'article: 177696 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Visual Basic peut créer des applications qui communiquent aux autres processus au moyen de canaux nommés. Le canal nommé doit être créé sur Windows 2000 ou Windows NT ; toutefois, vous pouvez lire et écrire sur ce canal à partir de n'importe quelle plate-forme 32 bits.

Cet article illustre la communication client/serveur à l'aide d'un canal nommé dans Visual Basic.

Plus d'informations

Dans cet article, le processus de création de la NamedPipe est appelé serveur et le processus de connexion au canal nommé est appelé le client.

Il y a six étapes pour la création d'un serveur de canal nommé :
  1. Créer un jeton de sécurité pour le canal autoriser l'accès (pour le rendre un canal nommé soit disponible pour n'importe quel processus en créant un jeton de sécurité avec un Access Control List discrétionnaire comportant zéro entrées).
  2. Créer le canal nommé.
  3. Appelez ConnectNamedPipe pour bloquer jusqu'à ce qu'un client se connecte.
  4. Appelez ReadFile et/ou WriteFile pour communiquer sur le canal de communication.
  5. Appelez DisconnectNamedPipe lorsque le processus est terminé à l'aide du canal.
  6. Soit CloseHandle sur le canal nommé, ou atteindre l'étape 4.
Il y a trois étapes pour utiliser un canal nommé à partir du client de canal nommé :
  1. Appelez CreateFile pour obtenir un handle pour le canal nommé.
  2. Appelez ReadFile et/ou WriteFile pour communiquer sur le canal de communication.
  3. Appeler CloseHandle sur filehandle créé dans CreateFile.
Ou bien, vous pouvez appeler CallNamedPipe qui effectue une transaction unique sur le canal. CallNamedPipe ouvre le tuyau, écrit, lit à partir de celui-ci, puis ferme le canal de communication. C'est ce que fait le client ci-dessous.

L'exemple suivant montre comment créer un client et un Named Pipe Server. Il implémente uniquement les fonctions plus rudimentaires nécessaires pour ce faire, avec un minimum de vérification des erreurs. Un programme entièrement fonctionnel doit vérifier les valeurs de retour de l'API est appelées, et non en supposant qu'ils ont réussi.

Serveur de canal nommé

  1. Créez un nouveau projet. Form1 est créé par défaut.
  2. Ajoutez le code suivant au formulaire :
       Option Explicit
       Private Const szPipeName = "\\.\pipe\bigtest"
       Private Const BUFFSIZE = 20000
       Private BigBuffer(BUFFSIZE) As Byte, pSD As Long
       Private sa As SECURITY_ATTRIBUTES
       Private hPipe As Long
    
       Private Sub Form_Click()
          Dim i As Long, dwOpenMode As Long, dwPipeMode As Long
          Dim res As Long, nCount As Long, cbnCount As Long
          For i = 0 To BUFFSIZE - 1       'Fill an array of numbers
             BigBuffer(i) = i Mod 256
          Next i
    
          'Create the NULL security token for the pipe
          pSD = GlobalAlloc(GPTR, SECURITY_DESCRIPTOR_MIN_LENGTH)
          res = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)
          res = SetSecurityDescriptorDacl(pSD, -1, 0, 0)
          sa.nLength = LenB(sa)
          sa.lpSecurityDescriptor = pSD
          sa.bInheritHandle = True
    
          'Create the Named Pipe
          dwOpenMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_WRITE_THROUGH
          dwPipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE
          hPipe = CreateNamedPipe(szPipeName, dwOpenMode, dwPipeMode, _
                                  10, 10000, 2000, 10000, sa)
    
          Do  'Wait for a connection, block until a client connects
             res = ConnectNamedPipe(hPipe, ByVal 0)
    
             'Read/Write data over the pipe
             cbnCount = 4
    
             res = ReadFile(hPipe, nCount, LenB(nCount), cbnCount, ByVal 0)
    
             If nCount <> 0 Then
    
                If nCount > BUFFSIZE Then 'Client requested nCount bytes
                   nCount = BUFFSIZE      'but only send up to 20000 bytes
                End If
                'Write the number of bytes requested
                res = WriteFile(hPipe, BigBuffer(0), nCount, cbnCount, ByVal 0)
                'Make sure the write is finished
                res = FlushFileBuffers(hPipe)
             End If
    
             'Disconnect the NamedPipe
             res = DisconnectNamedPipe(hPipe)
          Loop Until nCount = 0
    
          'Close the pipe handle
          CloseHandle hPipe
          GlobalFree (pSD)
          End
       End Sub
    					
  3. Créez un nouveau module et ajoutez les déclarations suivantes :
       Option Explicit
    
       Public Const FILE_ATTRIBUTE_NORMAL = &H80
       Public Const FILE_FLAG_NO_BUFFERING = &H20000000
       Public Const FILE_FLAG_WRITE_THROUGH = &H80000000
    
       Public Const PIPE_ACCESS_DUPLEX = &H3
       Public Const PIPE_READMODE_MESSAGE = &H2
       Public Const PIPE_TYPE_MESSAGE = &H4
       Public Const PIPE_WAIT = &H0
    
       Public Const INVALID_HANDLE_VALUE = -1
    
       Public Const SECURITY_DESCRIPTOR_MIN_LENGTH = (20)
       Public Const SECURITY_DESCRIPTOR_REVISION = (1)
    
       Type SECURITY_ATTRIBUTES
               nLength As Long
               lpSecurityDescriptor As Long
               bInheritHandle As Long
       End Type
    
       Public Const GMEM_FIXED = &H0
       Public Const GMEM_ZEROINIT = &H40
       Public Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)
    
       Declare Function GlobalAlloc Lib "kernel32" ( _
          ByVal wFlags As Long, ByVal dwBytes As Long) As Long
       Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
       Declare Function CreateNamedPipe Lib "kernel32" Alias _
          "CreateNamedPipeA" ( _
          ByVal lpName As String, _
          ByVal dwOpenMode As Long, _
          ByVal dwPipeMode As Long, _
          ByVal nMaxInstances As Long, _
          ByVal nOutBufferSize As Long, _
          ByVal nInBufferSize As Long, _
          ByVal nDefaultTimeOut As Long, _
          lpSecurityAttributes As Any) As Long
    
       Declare Function InitializeSecurityDescriptor Lib "advapi32.dll" ( _
          ByVal pSecurityDescriptor As Long, _
          ByVal dwRevision As Long) As Long
    
       Declare Function SetSecurityDescriptorDacl Lib "advapi32.dll" ( _
          ByVal pSecurityDescriptor As Long, _
          ByVal bDaclPresent As Long, _
          ByVal pDacl As Long, _
          ByVal bDaclDefaulted As Long) As Long
    
       Declare Function ConnectNamedPipe Lib "kernel32" ( _
          ByVal hNamedPipe As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function DisconnectNamedPipe Lib "kernel32" ( _
          ByVal hNamedPipe As Long) As Long
    
       Declare Function WriteFile Lib "kernel32" ( _
          ByVal hFile As Long, _
          lpBuffer As Any, _
          ByVal nNumberOfBytesToWrite As Long, _
          lpNumberOfBytesWritten As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function ReadFile Lib "kernel32" ( _
          ByVal hFile As Long, _
          lpBuffer As Any, _
          ByVal nNumberOfBytesToRead As Long, _
          lpNumberOfBytesRead As Long, _
          lpOverlapped As Any) As Long
    
       Declare Function FlushFileBuffers Lib "kernel32" ( _
          ByVal hFile As Long) As Long
    
       Declare Function CloseHandle Lib "kernel32" ( _
          ByVal hObject As Long) As Long
    					
  4. Enregistrez le formulaire.

Client de canal nommé

  1. Créez un nouveau projet. Form1 est créé par défaut.
  2. Ajoutez les contrôles suivants au formulaire :
       Type             Name               Caption/Default Value
       ----             ----               ---------------------
       TextBox          cbBytes            500
       CommandButton    cmdCallNamedPipe   Call Named Pipe
       TextBox          txtReceive
    					
  3. Ajoutez le code suivant au formulaire :
       Option Explicit
       Private Const szPipeName = "\\.\pipe\bigtest", BUFFSIZE = 20000
       Private Declare Function CallNamedPipe Lib "kernel32" Alias _
          "CallNamedPipeA" ( _
          ByVal lpNamedPipeName As String, _
          lpInBuffer As Any, _
          ByVal nInBufferSize As Long, _
          lpOutBuffer As Any, _
          ByVal nOutBufferSize As Long, _
          lpBytesRead As Long, _
          ByVal nTimeOut As Long) As Long
    
       Private Sub cmdCallNamedPipe_Click()
          Dim res As Long, myStr As String, i As Long, cbRead As Long
          Dim numBytes As Long, bArray() As Byte, temp As String
    
          numBytes = cbBytes.Text
          If cbBytes.Text < 0 Then
             MsgBox "Value must be at least 0.", vbOKOnly
             Exit Sub
          End If
          If numBytes > BUFFSIZE Then
             numBytes = BUFFSIZE
          End If
          ReDim bArray(numBytes)  'Build the return buffer
    
          'Call CallNamedPipe to do the transaction all at once
          res = CallNamedPipe(szPipeName, numBytes, LenB(numBytes), _
             bArray(0), numBytes, _
             cbRead, 30000) 'Wait up to 30 seconds for a response
    
          If res > 0 Then
             temp = Format(bArray(0), " 000")
             For i = 1 To cbRead - 1
                If (i Mod 16) = 0 Then temp = temp & vbCrLf
                temp = temp & " " & Format(bArray(i), "000")
             Next i
             txtReceive.Text = temp
          Else
             MsgBox "Error number " & Err.LastDllError & _
                    " attempting to call CallNamedPipe.", vbOKOnly
          End If
       End Sub
    
    					
  4. Notez que si le serveur s'exécute sur un ordinateur autre qu'où est le client, vous devez modifier le '. ' dans la variable szPipeName sur le nom de la machine serveur.
  5. Enregistrez le formulaire. Pour tester le code ci-dessus, tout d'abord démarrer le serveur et cliquez sur n'importe où dans le formulaire. L'application serveur est désormais de blocage et semble avoir bloqué, mais il est réellement attendre que le client pour se connecter. Démarrez l'application client puis cliquez sur "Appel nommé Pipe". Le client doit envoyer la valeur 500 au serveur qui répondra avec 500 octets de données. Vous pouvez définir la valeur dans la zone de texte cbBytes à partir de 0 à 20 000 octets. Pour arrêter le serveur, vous devez simplement envoyer 0 (zéro) à partir du client. Le client peut recevoir erreur 233 (ERROR_PIPE_NOT_CONNECTED), mais ceci est normal.

    Une autre amélioration à l'échantillon peut inclure l'utilisation de ports de terminaison d'e/S et/ou de blocage non lectures et écritures à l'aide d'e/S avec chevauchement. Vous trouverez plus d'informations sur ces sujets dans le Kit de développement Platform SDK.

Références

Plusieurs méthodes de Communication InterProcess (IPC) sont disponibles dans Windows 2000, Windows NT et Windows 95 autoriser le transfert unidirectionnelle ou bidirectionnelle des données entre plusieurs processus. Pour obtenir une liste complète des méthodes d'IPC disponibles sur chaque plate-forme, consultez l'article suivant dans la base de connaissances Microsoft :
95900: Communication entre processus sur Windows NT, Windows 95 et Win32s

Propriétés

Numéro d'article: 177696 - Dernière mise à jour: lundi 12 février 2007 - Version: 2.4
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Visual Basic 4.0 Édition professionnelle
  • Microsoft Visual Basic 5.0 Édition professionnelle
  • Microsoft Visual Basic 6.0 Édition professionnelle
  • Microsoft Visual Basic 4.0 Édition Entreprise
  • Microsoft Visual Basic 5.0 Édition Entreprise
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Windows NT 4.0
  • Microsoft Windows NT 3.51 Service Pack 5
  • Microsoft Windows NT 4.0
  • Microsoft Windows 98 Standard Edition
  • Microsoft Win32 Application Programming Interface
  • the operating system: Microsoft Windows 2000
  • Microsoft Windows 95
  • Microsoft Windows Millennium Edition
Mots-clés : 
kbmt kbapi kbhowto KB177696 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 177696
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com