Como usar pipes nomeados para comunicação entre processos no Visual Basic .NET ou no Visual Basic 2005

Sumário
Esse artigo discute detalhadamente como usar pipes nomeados no Microsoft Visual Basic .NET ou no Microsoft Visual Basic 2005 para comunicação entre processos. Esse artigo inclui um exemplo de código que demonstra a comunicação cliente/servidor usando um pipe nomeado no Visual Basic .NET ou no Visual Basic 2005. O artigo descreve a comunicação entre processos criando um servidor de pipe nomeado e um cliente de pipe nomeado. A comunicação através do pipe é executada da seguinte maneira:
  • Crie um pipe nomeado.
  • Bloqueie o aplicativo do servidor usando a função ConnectNamedPipe até que um cliente se conecte.
  • Conecte ao servidor usando a função CallNamedPipe.
  • Chame a função ReadFile ou WriteFile para se comunicar através do pipe.
  • Chame a função DisconnectNamedPipe quando o processo terminar de usar o pipe.
  • Chame a função CloseHandle no pipe nomeado após o término da comunicação através do pipe.
INTRODUÇÃO
Um pipe nomeado é um pipe unidirecional ou duplex para comunicação entre um servidor de pipe e um ou mais clientes de pipe. É possível usar pipes nomeados para fornecer comunicação entre processos no mesmo computador ou entre processos em diferentes computadores através de uma rede. O termo "servidor de pipe nomeado" refere-se a um processo que cria um pipe nomeado e o termo "cliente de pipe nomeado" refere-se a um processo que se conecta a uma instância de um pipe nomeado.

É possível usar o Microsoft Visual Basic .NET ou Microsoft Visual Basic 2005 para criar aplicativos que se comunicam com outros processos usando pipes nomeados. Esse artigo contém um exemplo de código que usa um pipe nomeado para se comunicar entre dois aplicativos do Visual Basic .NET ou Visual Basic 2005 Windows.

voltar ao início

Requisitos

Este artigo presume que você esteja familiarizado com os seguintes tópicos:
  • Aplicativos do Windows
  • Programação do Visual Basic .NET
  • Utilização de pipes
A seguinte lista descreve a infra-estrutura de rede, software, hardware e os service packs recomendados:
  • Microsoft Visual Studio .NET ou Microsoft Visual Studio 2005
  • Microsoft .NET Framework
voltar ao início

Criar um servidor de pipe nomeado

Para criar um servidor de pipe nomeado e se comunicar com o cliente através do pipe, execute as seguintes etapas:
  1. Crie um pipe nomeado.
  2. Chame a função ConnectNamedPipe para bloquear o servidor até que um cliente se conecte.
  3. Chame a função ReadFile ou WriteFile para se comunicar através do pipe.
  4. Chame a função DisconnectNamedPipe quando o processo terminar de usar o pipe.
  5. Chame a função CloseHandle no pipe nomeado.
voltar ao início

Projetar um aplicativo do Windows que cria um servidor de pipe nomeado

Para projetar um aplicativo do Windows que cria um servidor de pipe nomeado usando o Visual Basic .NET ou Visual Basic 2005, execute as seguintes etapas:
  1. Inicie o Microsoft Visual Studio .NET ou o Microsoft Visual Studio 2005.
  2. No menu File, aponte para New e clique em Project.
  3. Em Project Types, clique em Visual Basic Projects e clique em Windows Application em Templates.

    Observação No Visual Studio 2005, clique em Visual Basic em Project Types.
  4. Na caixa Name, digite MyServerApp e clique em OK. Por padrão, um formulário chamado Form1 é criado.
  5. Adicione três controles Button ao formulário Form1.
  6. No menu View, clique em Properties Window.
  7. Defina a propriedade Text dos controles Button aos seguintes valores:
    NameText
    Button1Crie um pipe nomeado
    Button2Aguarde as conexões do cliente
    Button3Desconecte o servidor
  8. Adicione um controle Label ao formulário Form1. O controle Label Label1 é adicionado ao formulário Form1.
voltar ao início

Adicionar todas as declarações a um módulo no aplicativo do Windows

Para adicionar as declarações da função necessárias para implementar a comunicação entre processos usando o pipe nomeado, execute as seguintes etapas:
  1. No Solution Explorer, clique com o botão direito do mouse em MyServerApp, aponte para Add e clique em Add Module.
  2. Na caixa de diálogo Add New Item - MyServerApp, clique em Open.
  3. Adicione o seguinte código ao módulo Module1.vb:
    Public Const FILE_ATTRIBUTE_NORMAL As Short = &H80SPublic Const FILE_FLAG_NO_BUFFERING As Integer = &H20000000Public Const FILE_FLAG_WRITE_THROUGH As Integer = &H80000000Public Const PIPE_ACCESS_DUPLEX As Short = &H3SPublic Const PIPE_READMODE_MESSAGE As Short = &H2SPublic Const PIPE_TYPE_MESSAGE As Short = &H4SPublic Const PIPE_WAIT As Short = &H0SPublic Const INVALID_HANDLE_VALUE As Short = -1Declare Function CreateNamedPipe Lib "kernel32" Alias "CreateNamedPipeA" _(ByVal lpName As String, ByVal dwOpenMode As Integer, _ByVal dwPipeMode As Integer, ByVal nMaxInstances As Integer, _ByVal nOutBufferSize As Integer, ByVal nInBufferSize As Integer, _ByVal nDefaultTimeOut As Integer, ByVal lpSecurityAttributes As IntPtr _) As IntegerDeclare Function ConnectNamedPipe Lib "kernel32" _    (ByVal hNamedPipe As Integer, ByVal lpOverlapped As Integer) As IntegerDeclare Function DisconnectNamedPipe Lib "kernel32" _    (ByVal hNamedPipe As Integer) As IntegerDeclare Function WriteFile Lib "kernel32" _(ByVal hFile As Integer, ByRef lpBuffer() As Byte, _ByVal nNumberOfBytesToWrite As Integer, ByRef lpNumberOfBytesWritten As Integer, _ByVal lpOverlapped As Integer _) As IntegerDeclare Function ReadFile Lib "kernel32" _(ByVal hFile As Integer, ByRef lpBuffer As Integer, _ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, _ByVal lpOverlapped As Integer _) As IntegerDeclare Function FlushFileBuffers Lib "kernel32" _    (ByVal hFile As Integer) As IntegerDeclare Function CloseHandle Lib "kernel32" _    (ByVal hObject As Integer) As Integer
voltar ao início

Escrever código para criar um servidor de pipe nomeado

Após a criação de um pipe nomeado, aguarde as conexões do cliente. Quando o cliente conecta ao servidor, leia ou escreva as dados através do pipe. Para fazer isto, execute as seguintes etapas:
  1. No Solution Explorer, clique com o botão direito do mouse em Form1 e clique em Open.
  2. Na exibição Design do formulário Form1, clique duas vezes em Create a named pipe e adicione o seguinte código ao procedimento Button1_Click:
    Dim openMode, pipeMode As Integer'Create the named pipeopenMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_WRITE_THROUGHpipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGEhPipe = CreateNamedPipe(pipeName, openMode, pipeMode, 10, 10000, 2000, 10000, IntPtr.Zero)Label1.Text = "Created the named pipe and waiting for the clients."Button1.Visible = FalseButton2.Visible = TrueButton3.Visible = True
  3. Adicione o seguinte código antes do procedimento Button1_Click:
    Private Const pipeName As String = "\\.\pipe\MyPipe"Private Const BUFFSIZE As Short = 10000Private Buffer(BUFFSIZE) As BytePrivate hPipe As Integer
  4. No Solution Explorer, clique duas vezes em Form1.vb.
  5. Na exibição Design do formulário Form1, clique duas vezes em Wait for the client connections e adicione o seguinte código ao procedimento Button2_Click:
    Dim byteCount, i, res, cbnCount As IntegerFor i = 0 To BUFFSIZE - 1 'Fill an array of numbers   Buffer(i) = i Mod 256Next i'Wait for a connection, block until a client connectsLabel1.Text = "Waiting for client connections"Me.Refresh()Do   res = ConnectNamedPipe(hPipe, 0)   'Read the data sent by the client over the pipe   cbnCount = 4   res = ReadFile(hPipe, byteCount, Len(byteCount), cbnCount, 0)   If byteCount > BUFFSIZE Then 'Client requested for byteCount bytes       byteCount = BUFFSIZE 'but only send up to 20000 bytes   End If   'Write the number of bytes requested by the client    res = WriteFile(hPipe, Buffer, byteCount, cbnCount, 0)   res = FlushFileBuffers(hPipe)   'Disconnect the named pipe.   res = DisconnectNamedPipe(hPipe)   'Loop until the client makes no more requests for data. Loop Until byteCount = 0Label1.Text = "Read or Write completed"Button2.Visible = False
  6. Na exibição Design, clique duas vezes em Form1 e adicione o seguinte código ao procedimento Form1_Load:
    Button2.Visible = FalseButton3.Visible = False
  7. No Solution Explorer, clique duas vezes em Form1.vb.
  8. Na exibição Design do formulário Form1, clique duas vezes em Disconnect the server e adicione o seguinte código ao procedimento Button3_Click:
    Dim res As Integer 'Close the pipe handle when the client makes no requests CloseHandle(hPipe) Label1.Text = "Disconnected the named pipe"
  9. No menu Build, clique em Build Solution.
voltar ao início

Criar um cliente de pipe nomeado

Para criar um cliente de pipe nomeado que se comunica com o servidor, execute as seguintes etapas:
  1. Chame a função CreateFile para criar um identificador para o pipe nomeado.
  2. Chame a função ReadFile ou WriteFile para se comunicar através do pipe.
  3. Chame a função CloseHandle no identificador criado na função CreateFile.
Também é possível usar uma transação de pipe nomeado para a comunicação cliente/servidor. A transação de pipe nomeado combina uma operação de escrita e uma operação de leitura em uma única operação de rede. Uma transação pode ser usada apenas em um pipe duplex do tipo mensagem. Os processos podem usar a função TransactNamedPipe ou a função CallNamedPipe para executar transações de pipe nomeado.

Neste exemplo de código, você usa a função CallNamedPipe para conectar ao servidor de pipe nomeado, escrever os dados no pipe e ler os dados no pipe.

voltar ao início

Projetar um aplicativo do Windows que se comunica com o servidor de pipe nomeado

Para projetar um aplicativo do Visual Basic .NET ou do Visual Basic 2005 Windows usado para conectar ao servidor de pipe nomeado, execute as seguintes etapas:
  1. Inicie o Microsoft Visual Studio .NET ou o Microsoft Visual Studio 2005.
  2. No menu File, aponte para New e clique em Project.
  3. Em Project Types, clique em Visual Basic Projects e clique em Windows Application em Templates.

    Observação No Visual Studio 2005, clique em Visual Basic em Project Types.
  4. Na caixa Name clique em MyClientApp e clique em OK. Por padrão, um formulário chamado Form1 é criado.
  5. Adicione um controle Button ao formulário Form1.
  6. Clique com o botão direito do mouse em Button1 e clique em Properties.
  7. Defina a propriedade Text como Connect to the server.
  8. Adicione um controle Label ao formulário Form1. O controle Label Label1 é adicionado ao formulário Form1.
  9. Defina a propriedade Visible do controle Label Label1 como False.
  10. Adicione dois controles TextBox ao formulário Form1.
voltar ao início

Escrever código para conectar ao servidor de pipe nomeado

Conecte ao servidor de pipe nomeado usando a função CallNamedPipe. Depois de conectar ao servidor, a função CallNamedPipe escreve para o pipe, lê no pipe e fecha o pipe. Para conectar ao servidor, ler e escrever os dados, execute as seguintes etapas:
  1. Na exibição Design, clique duas vezes em Connect to the server e adicione o seguinte código ao procedimento Button1_Click:
    Dim i, res, cbRead,numBytes As IntegerDim bArray() As ByteDim temp As StringnumBytes = CInt(TextBox1.Text)If numBytes < 0 Then    MessageBox.Show("Value must be at least 0.", MsgBoxStyle.OKOnly)    Exit SubEnd IfIf numBytes = 0 Then    Label1.Visible = True    Label1.Text = "The connection to the server is disconnected."    Button1.Visible = False    TextBox1.Visible = False    TextBox2.Visible = FalseEnd IfIf numBytes > BUFFSIZE Then    numBytes = BUFFSIZEEnd IfReDim bArray(numBytes) 'Create the return buffer'Call the CallNamedPipe function to do the transactions res = CallNamedPipe(pipeName, numBytes, Len(numBytes), bArray(0), numBytes, cbRead, 30000) 'Wait up to 30 seconds for a response'Format the data received, and then display the data in the text boxIf 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    TextBox2.Text = tempElseMessageBox.Show("Error number " & Err.LastDllError & _"while trying to call the CallNamedPipe function.", MsgBoxStyle.OKOnly)End If
  2. Adicione o seguinte código antes do procedimento Button1_Click:
    Private Const pipeName As String = "\\.\pipe\MyPipe" Private Const BUFFSIZE As Integer = 10000 Private hpipe As Integer      Public Const INVALID_HANDLE_VALUE As Short = -1 Public Declare Function CallNamedPipe Lib "kernel32" Alias "CallNamedPipeA" _ (ByVal lpNamedPipeName As String, _ ByRef lpInBuffer As Integer, _ ByVal nInBufferSize As Integer, _ ByRef lpOutBuffer As Byte, _ ByVal nOutBufferSize As Integer, _ ByRef lpBytesRead As Integer, ByVal nTimeOut As Integer) As Integer
  3. No menu Build, clique em Build Solution.
voltar ao início

Verificar se o código funciona

Para verificar se o código funciona, execute as seguintes etapas:
  1. Para iniciar o aplicativo do servidor, clique em Start no menu Debug do projeto MyServerApp.
  2. No formulário Form1, clique em Create a named pipe e em Wait for the client connections. Agora, o aplicativo está bloqueado e aguardando o cliente conectar.
  3. Para iniciar o aplicativo cliente, clique em Start no menu Debug do projeto MyClientApp.
  4. No formulário Form1, digite 10 na caixa TextBox1 e clique em Connect to the server. É possível ver a matriz de byte recebida na caixa TextBox2.
  5. Para desconectar o aplicativo cliente do servidor, digite 0 na caixa TextBox1 no aplicativo cliente e clique em Connect to the server.
  6. Feche o aplicativo cliente.
  7. Para desconectar a extremidade do servidor do pipe nomeado e fechar o aplicativo do servidor, clique em Disconnect the server no formulário Form1 do aplicativo do servidor.
voltar ao início
Referências
Para obter informações adicionais, visite os seguintes sites da Microsoft Developer Network (MSDN) (em inglês):voltar ao início
Proprietăți

ID articol: 871044 - Ultima examinare: 01/17/2008 23:25:00 - Revizie: 2.4

Microsoft Visual Basic 2005, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual Basic .NET 2002 Standard Edition

  • kbhowto kbhowtomaster kbpipes kbserver kbipc kbclient kbvs2005applies kbvs2005swept KB871044
Feedback