Compartilhar via


Como: Uso Named Pipes para comunicação entre processos através de uma rede

Pipes nomeados oferecem mais funcionalidades do que pipes anônimos.Essas funcionalidades incluem a comunicação full-duplex em uma rede e várias instâncias do servidor; comunicação baseada em mensagens; e personificação do cliente, o que permite que processos de conexão usem seus próprios conjuntos de permissões em servidores remotos.

Exemplo

O exemplo a seguir demonstra como criar um pipe nomeado usando a classe NamedPipeClientStream.Nesse exemplo, o processo do servidor cria quatro segmentos.Cada segmento pode aceitar uma conexão de cliente.O processo de cliente conectado, em seguida, fornece ao servidor um nome de arquivo.Se o cliente tiver permissões suficientes, o processo do servidor abre o arquivo e envia o conteúdo de volta para o cliente.

Imports System
Imports System.IO
Imports System.IO.Pipes
Imports System.Threading

Class PipeServer
    Shared numThreads As Integer = 4

    Shared Sub Main()
        Dim i As Integer
        For i = 1 To numThreads
            Dim newThread As New Thread(New ThreadStart(AddressOf ServerThread))
            newThread.Start()
        Next
    End Sub

    Private Shared Sub ServerThread()
        Dim pipeServer As New NamedPipeServerStream("testpipe", _
            PipeDirection.InOut, numThreads)

        Console.WriteLine("NamedPipeServerStream thread created.")

        ' Wait for a client to connect
        pipeServer.WaitForConnection()

        Console.WriteLine("Client connected.")
        Try
            ' Read the request from the client. Once the client has
            ' written to the pipe, its security token will be available.
            Dim sr As New StreamReader(pipeServer)
            Dim sw As New StreamWriter(pipeServer)
            sw.AutoFlush = True

            ' Verify our identity to the connected client using a
            ' string that the client anticipates.
            sw.WriteLine("I am the true server!")

            ' Obtain the filename from the connected client.
            Dim filename As String = sr.ReadLine()

            ' Read in the contents of the file while impersonating
            ' the client.
            Dim fileReader As New ReadFileToStream(pipeServer, filename)

            ' Display the name of the clientr we are impersonating.
            Console.WriteLine("Reading file: {0} as user {1}.", _
                filename, pipeServer.GetImpersonationUserName())

            pipeServer.RunAsClient(AddressOf fileReader.Start)

            pipeServer.Disconnect()

            sr.Close()
            sw.Close()
        Catch ex As Exception
            Console.WriteLine("ERROR: {0}", ex.Message)
        End Try
        pipeServer.Close()
    End Sub
End Class

Public Class ReadFileToStream
    Private m_filename As String
    Private m_stream As Stream

    Public Sub New(ByVal stream1 As Stream, ByVal filename As String)
        m_filename = filename
        m_stream = stream1
    End Sub

    Public Sub Start()
        Using sw As New StreamWriter(m_stream)
            Dim contents As String = File.ReadAllText(m_filename)
            sw.WriteLine(contents)
            sw.Flush()
        End Using
    End Sub
End Class
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;

class PipeServer
{
    static int numThreads = 4;

    static void Main()
    {
        for (int i = 0; i < numThreads; i++)
        {
            Thread newThread = new Thread(new ThreadStart(ServerThread));
            newThread.Start();
        }
        Console.WriteLine("Press enter to exit.");
        Console.ReadLine();
    } // Main()

    private static void ServerThread()
    {
        using (NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("testpipe", PipeDirection.InOut, numThreads))
        {
            Console.WriteLine("NamedPipeServerStream thread created.");

            // Wait for a client to connect
            pipeServer.WaitForConnection();

            Console.WriteLine("Client connected.");
            try
            {
                // Read the request from the client. Once the client has
                // written to the pipe its security token will be available.
                using (StreamReader sr = new StreamReader(pipeServer))
                using (StreamWriter sw = new StreamWriter(pipeServer))
                {
                    sw.AutoFlush = true;

                    // Verify our identity to the connected client using a
                    // string that the client anticipates.
                    sw.WriteLine("I am the true server!");

                    // Obtain the filename from the connected client.
                    string filename = sr.ReadLine();

                    // Read in the contents of the file while impersonating
                    // the client.
                    ReadFileToStream fileReader = new
                        ReadFileToStream(pipeServer, filename);

                    // Display the name of the user we are impersonating.
                    Console.WriteLine("Reading file: {0} as user {1}.",
                        pipeServer.GetImpersonationUserName(), filename);

                    pipeServer.RunAsClient(fileReader.Start);

                    pipeServer.Disconnect();
                }
           }
            // Catch the IOException that is raised if the pipe is broken
            // or disconnected.
            catch (IOException e)
            {
                Console.WriteLine("ERROR: {0}", e.Message);
            }
        }
    } // ServerThread()
} // PipeServer

class ReadFileToStream
{
    private string m_filename;
    private Stream m_stream;

    public ReadFileToStream(Stream stream, string filename)
    {
        m_filename = filename;
        m_stream = stream;
    } // ReadFileToStream(stream, filename)

    public void Start()
    {
        using (StreamWriter sw = new StreamWriter(m_stream))
        {
            string contents = File.ReadAllText(m_filename);
            sw.WriteLine(contents);
            sw.Flush();
        }
    } // Start()
} // ReadFileToStream

O exemplo a seguir mostra o processo de cliente, que usa a classe NamedPipeClientStream.O cliente conecta-se ao processo de servidor e envia um nome de arquivo para o servidor.O servidor, em seguida, envia o conteúdo do arquivo de volta para o cliente.O conteúdo do arquivo, em seguida, é exibido para o console.

Imports System
Imports System.IO
Imports System.IO.Pipes
Imports System.Security.Principal

Class PipeClient

    Shared Sub Main(ByVal args As String())

        Try
            Dim pipeClient As New NamedPipeClientStream("localhost", _
                        "testpipe", PipeDirection.InOut, PipeOptions.None, _
                        TokenImpersonationLevel.Impersonation)
            Dim sw As New StreamWriter(pipeClient)
            Dim sr As New StreamReader(pipeClient)
            sw.AutoFlush = True

            pipeClient.Connect()

            ' Verify that this is the "true server"
            'Dim serverID As String = sr.ReadLine()
            If 1 = 1 Then

                ' The client security token is sent with the first write
                sw.WriteLine("c:\textfile.txt")

                ' Print the file to the screen.
                Dim buffer(32) As Char
                Dim n As Integer

                n = sr.Read(buffer, 0, buffer.Length)
                While Not n = 0
                    Console.Write(buffer, 0, n)
                End While
            Else
                Console.WriteLine("Server could not be verified.")
            End If
            sw.Close()
            sr.Close()
            pipeClient.Close()
        Catch ex As Exception
            Console.WriteLine("ERROR: {0}", ex.Message)
        End Try
    End Sub
End Class
using System;
using System.IO;
using System.IO.Pipes;
using System.Security.Principal;

class PipeClient
{
    static int numThreads = 4;

    static void Main()
    {
        using (NamedPipeClientStream pipeClient = 
            new NamedPipeClientStream("localhost", "testpipe",
            PipeDirection.InOut, PipeOptions.None,
            TokenImpersonationLevel.Impersonation))
        using (StreamWriter sw = new StreamWriter(pipeClient))
        using (StreamReader sr = new StreamReader(pipeClient))
        {
            sw.AutoFlush = true;
            pipeClient.Connect();

            // Verify that this is the "true server"
            if (sr.ReadLine() == "I am the true server!")
            {
                // The client security token is sent with the first write.
                sw.WriteLine(@"c:\textfile.txt");

                // Print the file to the screen.
                char[] buffer = new char[32];
                int n;
                while ((n = sr.Read(buffer, 0, buffer.Length)) != 0)
                {
                    Console.Write(buffer, 0, n);
                }
            }
            else
            {
                Console.WriteLine("Server could not be verified.");
            }
        }
    } // Main()
}

Programação robusta

Os processos de cliente e servidor nesse exemplo destinam-se à execução no mesmo computador, portanto, o nome de servidor fornecido para o objeto NamedPipeClientStream é "localhost".Se os processos de cliente e servidor fossem em computadores separados, "localhost" deve ser substituído com o nome de rede do computador que executa o processo de servidor.

Consulte também

Tarefas

Como: Usar pipes anônimo para comunicação entre processos locais

Conceitos

Pipes