NamedPipeServerStream
namespace System.IO.Pipes
{
public sealed class NamedPipeServerStream : PipeStream
{
public const int MaxAllowedServerInstances = -1;
public NamedPipeServerStream(string pipeName);
public NamedPipeServerStream(string pipeName, PipeDirection direction);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode);
public NamedPipeServerStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights);
~NamedPipeServerStream();
public string GetImpersonationUserName();
public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker);
public void WaitForConnection();
public Task WaitForConnectionAsync(CancellationToken cancellationToken);
public Task WaitForConnectionAsync();
public IAsyncResult BeginWaitForConnection(AsyncCallback callback, object state);
public void EndWaitForConnection(IAsyncResult asyncResult);
public void Disconnect();
}
}
NamedPipeClientStream
namespace System.IO.Pipes
{
public sealed class NamedPipeClientStream : PipeStream
{
public NamedPipeClientStream(string pipeName);
public NamedPipeClientStream(string serverName, string pipeName);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction, PipeOptions options);
public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability);
public NamedPipeClientStream(string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability);
~NamedPipeClientStream();
public int NumberOfServerInstances { get; }
public void Connect();
public void Connect(int timeout);
public Task ConnectAsync();
public Task ConnectAsync(int timeout);
public Task ConnectAsync(CancellationToken cancellationToken);
public Task ConnectAsync(int timeout, CancellationToken cancellationToken);
protected internal override void CheckPipePropertyOperations();
}
}
- 같은 이름의 파이프 하나를 이용해서 통신
1. 서버가 NamedPipeServerStream 인스턴스를 생성하여 WaitForConnection을 호출
2. 클라이언트가 NamedPipeClientStream 인스턴스를 생성하여 Connect를 호출
3. 스트림 인스턴스를 읽고 쓰기
PipeDirection 열거형
namespace System.IO.Pipes
{
public enum PipeDirection
{
In = 1,
Out = 2,
InOut = 3
}
}
- 파이프의 방향 지정
반응형
PipeTransmissionMode 열거형
namespace System.IO.Pipes
{
public enum PipeTransmissionMode
{
Byte = 0,
Message = 1
}
}
- 일반적인 바이트 모드로 보낼것인지, 혹은 메시지 전송 모드로 보낼 것인지
- 전송 모드를 켤 경우 IsMessageComplete로 메시지를 완전히 읽었는지 판단
PipeOptions 열거형
PipeSecurity 클래스
namespace System.IO.Pipes
{
public class PipeSecurity : NativeObjectSecurity
{
public PipeSecurity();
public override Type AccessRightType { get; }
public override Type AccessRuleType { get; }
public override Type AuditRuleType { get; }
public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type);
public void AddAccessRule(PipeAccessRule rule);
public void SetAccessRule(PipeAccessRule rule);
public bool RemoveAccessRule(PipeAccessRule rule);
public void RemoveAccessRuleSpecific(PipeAccessRule rule);
public void ResetAccessRule(PipeAccessRule rule);
public sealed override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags);
public void AddAuditRule(PipeAuditRule rule);
public void SetAuditRule(PipeAuditRule rule);
public bool RemoveAuditRule(PipeAuditRule rule);
public void RemoveAuditRuleSpecific(PipeAuditRule rule);
public void RemoveAuditRuleAll(PipeAuditRule rule);
protected internal void Persist(SafeHandle handle);
protected internal void Persist(string name);
}
}
- FileSecurity와 마찬가지로 파이프에 대한 보안 관련인듯? Access Rule과 Audit Rule 설정
HandleInheritability 열거형
- 자식 프로세스에게 파이프의 핸들을 상속할지 여부 설정
PipeAccessRights 열거형
namespace System.IO.Pipes
{
public enum PipeAccessRights
{
ReadData = 1,
WriteData = 2,
CreateNewInstance = 4,
ReadExtendedAttributes = 8,
WriteExtendedAttributes = 16,
ReadAttributes = 128,
WriteAttributes = 256,
Write = 274,
Delete = 65536,
ReadPermissions = 131072,
Read = 131209,
ReadWrite = 131483,
ChangePermissions = 262144,
TakeOwnership = 524288,
Synchronize = 1048576,
FullControl = 2032031,
AccessSystemSecurity = 16777216
}
}
- 파이프에 대한 추가적인 권한 설정
TokenImpersonationLevel 열거형
namespace System.Security.Principal
{
public enum TokenImpersonationLevel
{
None = 0,
Anonymous = 1,
Identification = 2,
Impersonation = 3,
Delegation = 4
}
}
- 서버 프로세스가 클라이언트 프로세스의 권한을 가장하는 것에 대한 설정
- 책에는 내용이 없고 검색해보니 ASP가 나오는데... 아마 클라이언트의 설정을 배껴오는? 그런 류의 설정인듯.
예제
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
namespace Test
{
class Program
{
static void Main(string[] args)
{
bool isServer = true;
if (isServer)
{
// 메시지 모드로 인스턴스를 생성
using (var npss = new NamedPipeServerStream("myPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message))
{
// 클라이언트의 접속 대기
npss.WaitForConnection();
// UTF8로 인코딩해서 전송
byte[] byteMessage = Encoding.UTF8.GetBytes("안녕하세요 반갑습니다!");
npss.Write(byteMessage, 0, byteMessage.Length);
// 클라이언트의 메시지를 전송 받음
Console.WriteLine(Encoding.UTF8.GetString(ReadMessage(npss)));
}
}
else
{
using (var npcs = new NamedPipeClientStream("myPipe"))
{
// 서버로 접속
npcs.Connect();
// 읽기 모드를 메시지로 설정
npcs.ReadMode = PipeTransmissionMode.Message;
// 스트림을 읽어와 출력
Console.WriteLine(Encoding.UTF8.GetString(ReadMessage(npcs)));
// UTF8로 인코딩해서 전송
byte[] byteMessage = Encoding.UTF8.GetBytes("메시지 잘 받았습니다!");
npcs.Write(byteMessage, 0, byteMessage.Length);
}
}
Console.WriteLine("아무키나 눌러 종료!");
Console.ReadKey(true);
}
static byte[] ReadMessage(PipeStream ps)
{
// 배열로의 복사를 용이하게 하기 위한 메모리 스트림
var ms = new MemoryStream();
// 버퍼 사이즈는 4KB
var buffer = new byte[0x1000];
// 1. 파이프 스트림에서 읽어서 버퍼에 저장
// 2. 메모리 스트림에 버퍼에 있던 내용을 저장
// 3. 남은 메시지가 있다면 1~2를 반복
do
{
ms.Write(buffer, 0, ps.Read(buffer, 0, buffer.Length));
}
while (!ps.IsMessageComplete);
// 바이트 배열로 만들어서 리턴
return ms.ToArray();
}
}
}
반응형
'C#' 카테고리의 다른 글
[C#] PipeStream (0) | 2023.12.01 |
---|---|
[C#] MemoryStream (0) | 2023.11.24 |
[C#] FileStream (0) | 2023.11.20 |
[C#] Stream (0) | 2023.11.17 |
[C#] Task (0) | 2023.11.06 |
[C#] Thread (0) | 2023.11.01 |
[C#] Stopwatch (0) | 2023.10.30 |
[C#] PerformanceCounter, PerformanceCounterCategory (0) | 2023.10.28 |