C#使用命名管道通過網路在程式之間進行通訊
from MSDN
命名管道提供的功能比匿名管道多。其功能包括通過網路進行全雙工通訊和多個伺服器例項;基於訊息的通訊;以及客戶端模擬,這使得連線程式可在遠端伺服器上使用其自己的許可權集。
下面的示例演示如何使用NamedPipeServerStream類建立命名管道。在此示例中,伺服器程式建立了四個執行緒。每個執行緒可以接受一個客戶端連線。連線的客戶端程式隨後向伺服器提供一個檔名。如果客戶端具有足夠的許可權,伺服器程式就會開啟檔案並將其內容傳送回客戶端。
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
public class PipeServer
{
private static int numThreads = 4;
public static void Main()
{
int i;
Thread[] servers = new Thread[numThreads];
Console.WriteLine("\n*** Named pipe server stream with impersonation example ***\n");
Console.WriteLine("Waiting for client connect...\n");
for (i = 0; i < numThreads; i++)
{
servers[i] = new Thread(ServerThread);
servers[i].Start();
}
Thread.Sleep(250);
while (i > 0)
{
for (int j = 0; j < numThreads; j++)
{
if (servers[j] != null)
{
if (servers[j].Join(250))
{
Console.WriteLine("Server thread[{0}] finished.", servers[j].ManagedThreadId);
servers[j] = null;
i--; // decrement the thread watch count
}
}
}
}
Console.WriteLine("\nServer threads exhausted, exiting.");
}
private static void ServerThread(object data)
{
NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe", PipeDirection.InOut, numThreads);
int threadId = Thread.CurrentThread.ManagedThreadId;
// Wait for a client to connect
pipeServer.WaitForConnection();
Console.WriteLine("Client connected on thread[{0}].", threadId);
try
{
// Read the request from the client. Once the client has
// written to the pipe its security token will be available.
StreamString ss = new StreamString(pipeServer);
// Verify our identity to the connected client using a
// string that the client anticipates.
ss.WriteString("I am the one true server!");
string filename = ss.ReadString();
// Read in the contents of the file while impersonating the client.
ReadFileToStream fileReader = new ReadFileToStream(ss, filename);
// Display the name of the user we are impersonating.
Console.WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",
filename, threadId, pipeServer.GetImpersonationUserName());
pipeServer.RunAsClient(fileReader.Start);
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
pipeServer.Close();
}
}
// Defines the data protocol for reading and writing strings on our stream
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len = 0;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
// Contains the method executed in the context of the impersonated user
public class ReadFileToStream
{
private string fn;
private StreamString ss;
public ReadFileToStream(StreamString str, string filename)
{
fn = filename;
ss = str;
}
public void Start()
{
string contents = File.ReadAllText(fn);
ss.WriteString(contents);
}
}
下面的示例演示使用NamedPipeClientStream類的客戶端程式。客戶端連線伺服器程式並向伺服器傳送一個檔名。該示例使用模擬,所以執行客戶端應用程式的標識必須具有訪問檔案的許可權。伺服器隨後將檔案內容傳送回客戶端。檔案內容隨後顯示在控制檯上。
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Security.Principal;
using System.Diagnostics;
using System.Threading;
public class PipeClient
{
private static int numClients = 4;
public static void Main(string[] Args)
{
if (Args.Length > 0)
{
if (Args[0] == "spawnclient")
{
NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "testpipe",
PipeDirection.InOut, PipeOptions.None,
TokenImpersonationLevel.Impersonation);
Console.WriteLine("Connecting to server...\n");
pipeClient.Connect();
StreamString ss = new StreamString(pipeClient);
// Validate the server's signature string
if (ss.ReadString() == "I am the one true server!")
{
// The client security token is sent with the first write.
// Send the name of the file whose contents are returned
// by the server.
ss.WriteString("c:\\textfile.txt");
// Print the file to the screen.
Console.Write(ss.ReadString());
}
else
{
Console.WriteLine("Server could not be verified.");
}
pipeClient.Close();
// Give the client process some time to display results before exiting.
Thread.Sleep(4000);
}
}
else
{
Console.WriteLine("\n*** Named pipe client stream with impersonation example ***\n");
StartClients();
}
}
// Helper function to create pipe client processes
private static void StartClients()
{
int i;
string currentProcessName = Environment.CommandLine;
Process[] plist = new Process[numClients];
Console.WriteLine("Spawning client processes...\n");
if (currentProcessName.Contains(Environment.CurrentDirectory))
{
currentProcessName = currentProcessName.Replace(Environment.CurrentDirectory, String.Empty);
}
// Remove extra characters when launched from Visual Studio
currentProcessName = currentProcessName.Replace("\\", String.Empty);
currentProcessName = currentProcessName.Replace("\"", String.Empty);
for (i = 0; i < numClients; i++)
{
// Start 'this' program but spawn a named pipe client.
plist[i] = Process.Start(currentProcessName, "spawnclient");
}
while (i > 0)
{
for (int j = 0; j < numClients; j++)
{
if (plist[j] != null)
{
if (plist[j].HasExited)
{
Console.WriteLine("Client process[{0}] has exited.",
plist[j].Id);
plist[j] = null;
i--; // decrement the process watch count
}
else
{
Thread.Sleep(250);
}
}
}
}
Console.WriteLine("\nClient processes finished, exiting.");
}
}
// Defines the data protocol for reading and writing strings on our stream
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
此示例中的客戶端程式和伺服器程式預期在同一臺計算機上執行,因此提供給NamedPipeClientStream物件的伺服器名稱是"."。如果客戶端程式和伺服器程式位於不同的計算機上,則應該用執行伺服器程式的計算機的網路名稱來替換"."。
相關文章
- linux 程式間通訊之管道Linux
- Linux系統程式設計之程式間通訊方式:命名管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:命名管道(一)Linux程式設計
- 溫故之.NET程式間通訊——管道
- Linux 的程式間通訊:管道Linux
- 利用windows api實現程式通訊(命名管道)WindowsAPI
- 使用UDP如何進行網路通訊UDP
- 在Go和Python之間通過ActiveMQ通訊GoPythonMQ
- Linux程式間通訊②:有名管道FIFOLinux
- linux程式間通訊--管道(PIPE & FIFO)Linux
- C#使用SendMessage進行程序間通訊C#行程
- 程序間通訊(1)-管道
- 管道流間的通訊
- Linux系統程式設計之程式間通訊方式:管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:管道(一)Linux程式設計
- USB共享網路:android手機通過USB與Ubuntu進行socket網路通訊AndroidUbuntu
- 採用管道進行通訊的例子
- Linux 下的程式間通訊:使用管道和訊息佇列Linux佇列
- C# 使用SuperSocket的FixedHeaderReceiveFilter進行通訊C#HeaderFilter
- 通過串列埠進行通訊 :串列埠
- Java的通過管道來實現執行緒通訊Java執行緒
- 微服務之間通過RabbitMQ通訊微服務MQ
- 20.2、python程式間通訊——佇列和管道Python佇列
- Windows 中的命名管道(Named Pipes)是一種在程序間進行通訊的機制。它允許兩個或多個程序之間透過檔案系統的一個特殊路徑進行通訊,從而實現資料的傳輸和共享。Windows
- Android 程式之間通訊Android
- 3|程式間通訊--有名管道學習筆記筆記
- 通過 App Groups 實現程式間通訊APP
- 在 Laravel 中使用 Workerman 進行 socket 通訊Laravel
- linux 程式間通訊之FIFOLinux
- Linux程式之間如何通訊?Linux
- 利用管道Pipelines做程序間的通訊
- 通過進攻心態進行有效的網路防禦
- 系統程式設計——管道通訊程式設計
- Electron實戰之程式間通訊
- 網路通訊程式設計程式設計
- 在短視訊時代怎樣通過“優獲客”的方式進行網路營銷
- 在 OpenResty 裡實現程式間通訊REST
- 一文搞懂如何使用Node.js進行TCP網路通訊Node.jsTCP
- 多執行緒之間的通訊執行緒