博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
How to: Use Named Pipes to Communicate Between Processes over a Network
阅读量:4116 次
发布时间:2019-05-25

本文共 9540 字,大约阅读时间需要 31 分钟。

Named pipes offer more functionality than anonymous pipes. This functionality includes full duplex communication over a network and multiple server instances; message-based communication; and client impersonation, which enables connecting processes to use their own set of permissions on remote servers.


The following example demonstrates how to create a named pipe by using the  class. In this example, the server process creates four threads. Each thread can accept a client connection. The connected client process then supplies the server with a file name. If the client has sufficient permissions, the server process opens the file and sends its contents back to the client.

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 streampublic 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 userpublic 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);    }}

The following example shows the client process, which uses the  class. The client connects to the server process and sends a file name to the server. The server then sends the contents of the file back to the client. The file contents are then displayed to the console.

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 streampublic 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;    }}

The client and server processes in this example are intended to run on the same computer, so the server name provided to the  object is "localhost". If the client and server processes were on separate computers, "localhost" would be replaced with the network name of the computer that runs the server process.

转载地址:http://rjupi.baihongyu.com/

你可能感兴趣的文章
如何使用HTML和CSS进行分页?
查看>>
手把手教你实现图片懒加载
查看>>
7种在React中使用CSS的方式
查看>>
jQuery中的39个技巧
查看>>
3个非常棒的CSS技巧,可以在项目中完全代替JS
查看>>
用纯css模拟下雪的效果
查看>>
6个在Vue.js编写更好v-for循环的技巧
查看>>
42个来自《 CSS世界》中的实用技巧
查看>>
14个 JavaScript 中鲜为人知的技巧
查看>>
自动增长Textareas的最干净技巧
查看>>
如何只用HTML创建一个时间计划表?
查看>>
8个非常实用的Vue自定义指令
查看>>
如何将JavaScript中的JSON字符串转换为JSON对象数组?
查看>>
Vue开发之vue-router的基本使用
查看>>
JS中一定要了解的数据类型和数据转换
查看>>
vue 项目如何使用animate.css
查看>>
11个棘手的JavaScript面试题
查看>>
10个CSS3动画工具,值得你收藏!
查看>>
12种最常见的JavaScript数字方法
查看>>
10种JS速记技巧
查看>>