Freigeben über


Gewusst wie: Verwenden von benannten Pipes zur Kommunikation zwischen Prozessen über ein Netzwerk

Aktualisiert: November 2007

Benannte Pipes bieten mehr Funktionen als anonyme Pipes. Diese Funktionen umfassen Vollduplexkommunikation über ein Netzwerk und mehrere Serverinstanzen, meldungsbasierte Kommunikation und Clientidentitätswechsel, die verbindenden Prozessen die Verwendung ihrer eigenen Berechtigungen auf Remoteservern ermöglichen.

Beispiel

Das folgende Beispiel zeigt, wie eine benannte Pipe mit der NamedPipeClientStream-Klasse erstellt wird. In diesem Beispiel erstellt der Serverprozess vier Threads. Jeder Thread kann eine Clientverbindung akzeptieren. Der verbundene Clientprozess sendet daraufhin einen Dateinamen an den Server. Wenn der Client über ausreichende Berechtigungen verfügt, öffnet der Serverprozess die Datei und sendet ihren Inhalt an den Client zurück.

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

Das folgende Beispiel zeigt den Clientprozess, der die NamedPipeClientStream-Klasse verwendet. Der Client stellt eine Verbindung mit dem Serverprozess her und sendet einen Dateinamen an den Server. Anschließend sendet der Server den Inhalt der Datei an den Client zurück. Der Inhalt der Datei wird daraufhin auf der Konsole angezeigt.

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()
}

Robuste Programmierung

Der Client- und der Serverprozess in diesem Beispiel sind zur Ausführung auf dem gleichen Computer vorgesehen, sodass der Servername, der dem NamedPipeClientStream-Objekt bereitgestellt wird, "localhost" lautet. Wenn der Client- und der Serverprozess auf verschiedenen Computern ausgeführt würden, würde "localhost" durch den Netzwerknamen des Computers ersetzt, auf dem der Serverprozess ausgeführt wird.

Siehe auch

Aufgaben

Gewusst wie: Verwenden von anonymen Pipes zur Kommunikation zwischen lokalen Prozessen

Konzepte

Pipes