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