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

ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.

Эта статья на английском языке:177696
Аннотация
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 — последний просмотр: 11/14/2010 11:49:00 — редакция: 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
Отзывы и предложения