С помощью именованных каналов в 32-разрядной программы на Visual Basic

Переводы статьи Переводы статьи
Код статьи: 177696 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Аннотация

Visual Basic можно создавать приложения, взаимодействующие с другими процессами для именованных каналов. В Windows 2000 или Windows NT должна быть создана именованного канала; тем не менее, чтение и запись к этому каналу из любой 32-разрядной платформе.

В этой статье показано взаимодействие клиент сервер, с помощью именованных каналов в Visual Basic.

Дополнительная информация

В данной статье процесс создания NamedPipe называется сервер, и процесс, подключение к именованному каналу, называется клиентом.

Существуют шесть шагов для создания именованных каналов сервера.
  1. Создайте маркер безопасности для канала для доступа к нему (чтобы сделать доступными для любого процесса именованных каналов, создавая маркер безопасности с на уровне пользователей управления доступом список (DACL), содержит нулевые элементы).
  2. Создание именованного канала.
  3. Вызов ConnectNamedPipe для блокирования до подключения клиента.
  4. Вызов ReadFile и WriteFile для связи через канал.
  5. После завершения процесса, вызов DisconnectNamedPipe через канал.
  6. Либо CloseHandle по именованному каналу или перейдите к шагу 4.
Существуют три шага для использования именованных каналов клиентом именованных каналов.
  1. Вызовите CreateFile, чтобы получить дескриптор для именованного канала.
  2. Вызов ReadFile и WriteFile для связи через канал.
  3. Вызов CloseHandle filehandle, созданные в CreateFile.
Кроме того можно вызвать CallNamedPipe, который выполняет операцию однократного через канал. CallNamedPipe открытия канала, записывает в него, считывает из него, а затем закрывает канал. Это действие клиента ниже.

Следующий пример демонстрирует создание именованных каналов сервера и клиента. Она реализует наиболее элементарные функции, необходимые для этого с минимальным количеством ошибок. Полностью функциональное приложение должно проверять API, вызываемых возвращаемые значения, а не при условии, что они были успешно.

Именованный канал сервера

  1. Создайте новый проект.. По умолчанию будет создана форма Form1..
  2. Добавьте следующий код в форму:
       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. Создайте новый модуль и добавьте следующие объявления:
       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. Сохраните форму.

Именованный канал клиента

  1. Создайте новый проект.. По умолчанию будет создана форма Form1..
  2. Добавьте в форму следующие элементы:
       Type             Name               Caption/Default Value
       ----             ----               ---------------------
       TextBox          cbBytes            500
       CommandButton    cmdCallNamedPipe   Call Named Pipe
       TextBox          txtReceive
    					
  3. Добавьте следующий код в форму:
       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. Обратите внимание на то, что если сервер выполняется на компьютере, отличный от того, где находится клиент, необходимо изменить "." в переменной szPipeName имя компьютера сервера.
  5. Сохраните форму. Чтобы проверить приведенный выше код, сначала запустите сервер и щелкните на форме. Приложение-сервер имеет теперь блокировки и будет зависла, но он действительно ожидает подключения клиента. Затем запустите клиентское приложение и нажмите кнопку «вызов именованного канала.» Клиент должен отправить значение 500 серверу, который ответит с 500 байт данных. Может принимать значение в текстовом поле cbBytes от 0 до 20000 байт. Чтобы остановить сервер, просто отправьте 0 (ноль) от клиента. Клиент может появиться ошибка 233 (ERROR_PIPE_NOT_CONNECTED), но это не ошибка.

    Другое улучшение в пример может включать в себя использование портов завершения ввода-ВЫВОДА и/или блокировки не операций чтения и записи с помощью операций ввода-ВЫВОДА Overlapped. Дополнительные сведения по этим вопросам можно найти в пакете Microsoft Platform SDK.

Ссылки

В Windows 2000, Windows NT и Windows 95, позволяющие одностороннее или двустороннее передачи данных между несколькими процессами, существует несколько методов InterProcess взаимодействия (IPC). Для получения полного списка IPC методов, доступных на каждой из платформ обратитесь к следующей статье Microsoft Knowledge Base:
95900: Межпроцессного взаимодействия, в Windows NT, Windows 95 и Win32s

Свойства

Код статьи: 177696 - Последний отзыв: 14 ноября 2010 г. - Revision: 2.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 4.0 Enterprise Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Windows 98 Standard Edition
  • Microsoft Win32 Application Programming Interface
  • операционная система Microsoft Windows Millennium Edition
Ключевые слова: 
kbapi kbhowto kbmt KB177696 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:177696

Отправить отзыв

 

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