방법: 명명된 파이프를 사용하여 네트워크를 통한 프로세스 간 통신
업데이트: 2007년 11월
명명된 파이프는 익명 파이프보다 많은 기능을 제공합니다. 이러한 기능에는 네트워크 및 다중 서버 인스턴스를 통한 양방향 통신, 메시지 기반 통신 및 연결 프로세스가 원격 서버에서 고유한 권한 집합을 사용할 수 있는 클라이언트 가장이 있습니다.
예제
다음 예제에서는 NamedPipeClientStream 클래스를 사용하여 명명된 파이프를 만드는 방법을 보여 줍니다. 이 예제에서 서버 프로세스는 네 개의 스레드를 만듭니다. 각 스레드는 클라이언트 연결을 받아들일 수 있습니다. 그러면 연결된 클라이언트 프로세스가 서버에 파일 이름을 제공합니다. 클라이언트에 충분한 권한이 있으면 서버 프로세스가 파일을 열고 파일의 내용을 클라이언트에 다시 보냅니다.
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
다음 예제에서는 NamedPipeClientStream 클래스를 사용하는 클라이언트 프로세스를 보여 줍니다. 클라이언트는 서버 프로세스에 연결하고 서버에 파일 이름을 보냅니다. 그러면 서버가 파일의 내용을 클라이언트에 다시 보내고 이 파일 내용이 콘솔에 표시됩니다.
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()
}
강력한 프로그래밍
이 예제의 클라이언트 프로세스와 서버 프로세스는 동일한 컴퓨터에서 실행하기 위한 것이므로 NamedPipeClientStream 개체에 제공되는 서버 이름은 "localhost"입니다. 클라이언트 프로세스와 서버 프로세스가 서로 다른 컴퓨터에 있으면 "localhost"가 서버 프로세스를 실행하는 컴퓨터의 네트워크 이름으로 바뀝니다.