zoukankan      html  css  js  c++  java
  • 【C#】解析C#中管道流的使用

    目录结构:

    contents structure [+]

    管道为进程间通信提供了一种可能。管道分为两种,一种是匿名管道,另一种是命名管道。

    1.匿名管道(anonymous pipe)

    匿名管道,匿名管道只提供在本地电脑进程间的通信。匿名管道比命名管道花费的开销更少,但提供的服务也比命名管道的少。匿名管道是单向的,而且不能用于网络通信。匿名管道只支持单服务器实例。

    匿名管道不支持消息传输模式(PipeTransmissionMode.Message),仅支持字节传输模式(PipeTransmissionMode.Byte)。

    创建匿名管道需要使用AnonymousPipeClientStream和AnonymousPipeServerStream类,下面的案例展示了匿名的管道的用法。
    首先创建一个PipeServer.cs文件,其内容如下:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.IO.Pipes;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace PipeServer
    {
        class Program
        {
            static void Main(string[] args)
            {
                Process pipeClient1=new Process();
                pipeClient1.StartInfo.FileName = @"PipeClient.exe";
                            
                //AnonymousPipeServerStream is an one-way pipe. in other words it's only support PipeDirection.In or PipeDirection.Out.
                //in this program, we use PipeDirection.Out for send data to clients.
                using (AnonymousPipeServerStream pipeServer = 
                    new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable)) {
    
                    //send the client handle that from AnonymousPipeServerStream to client
                    pipeClient1.StartInfo.Arguments = pipeServer.GetClientHandleAsString();
                    pipeClient1.StartInfo.UseShellExecute = false;
                    pipeClient1.Start();
                    
                    //closes the local copy of the AnonymousPipeClientStream object's handle
                    //this method must be call after the client handle has been passed to the client
                    //if this method isn't called, then the AnonymousPipeServerStream will not receive notice when client dispose of it's PipeStream object
                    pipeServer.DisposeLocalCopyOfClientHandle();
    
                    try
                    {
                        using(StreamWriter sw=new StreamWriter(pipeServer)){
                            //automatic flush
                            sw.AutoFlush = true;
                            
                            sw.WriteLine("SYNC");
                            //it'll block util the other end of pipe has been read all send bytes
                            pipeServer.WaitForPipeDrain();
                            
                            String temp=null;
                            while(true){
                                temp=Console.ReadLine();
                                //send message to pipeclient from console
                                sw.WriteLine(temp);
                                //it'll block util the other end of pipe has been read all send bytes
                                pipeServer.WaitForPipeDrain();
                                if(temp=="exit"){
                                    break;
                                }
                            }
                        }
                    }
                    catch (IOException e) {
                        Console.WriteLine("[server] exception:{0}",e.Message);
                    }
                }
                
                pipeClient1.WaitForExit();
                pipeClient1.Close();
            
            }
        }
    }
    PipeServer.cs

    然后创建PipeClient.cs文件,内容如下:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Pipes;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
        class Program
        {
            static void Main(string[] args)
            {
                
                using (PipeStream pipeClient = new AnonymousPipeClientStream(PipeDirection.In, args[0])) {
    
                    using (StreamReader sr = new StreamReader(pipeClient)) {
                        String temp = null;
                        Console.WriteLine("[client] wait for sync ...");
                        do{
                            temp = sr.ReadLine();
                        }while(!temp.StartsWith("SYNC"));
                        Console.WriteLine("client in");
                        while ((temp = sr.ReadLine()) != null)
                        {
                            Console.WriteLine("[client] receive message: " + temp);
                            if(temp=="exit"){
                                break;
                            }
                        }
                    }
                    Console.Write("[client] Press Enter to exist...");
                    Console.ReadLine();
                }
            }
        }
    PipeClient.cs


    这里只展示一个服务端一个客户端,但实际中可以有多个客户端。PipeClient.cs和PipeServer.cs应该在同一个文件夹下面,具体的路径由PipeServer.cs中加载客户端的路径决定,本例中是在同一路径下。然后可以使用csc将其都编译为可执行文件。

    2.命名管道(named pipe)

    命名管道和匿名管道的功能相似,但他们有如下两点区别:

    • 命名管道既可以支持直接传输模式(PipeTransmissionMode.Byte),也可以支持消息传输模式(PipeTransmissionMode.Message)
    • 命名管道既可以用于本地进程间的通信,也可以用于网络通信。


    创建命名管道需要使用NamedPipeServerStream和NamedPipeClientStream类,下面的案例展示了命名管道的用法:
    PipeServer.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Pipes;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace PipeServer
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Waiting client to connect...
    ");
    
                using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
                {
    
                    //wait client to connect
                    pipeServer.WaitForConnection();
    
                    Console.WriteLine("[server] a client connected");
    
                    StreamReader reader = new StreamReader(pipeServer);
                    StreamWriter writer = new StreamWriter(pipeServer);
                    writer.AutoFlush = true;
    
                    String line = null;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Console.WriteLine("[server] receive message:"+line);
    
                        writer.WriteLine("I'm fine");
    
                        pipeServer.WaitForPipeDrain();
    
                        if ("line" == "EXIT")
                        {
                            break;
                        }
                    }
                };
    
                Console.ReadLine();
            }
        }
    }
    PipeServer.cs

    PipeClient.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Pipes;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace PipeClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                //initialize NamePipeClientStream with serverName,pipeName,pipeDirection
                using (NamedPipeClientStream pipeClient =
                new NamedPipeClientStream("host path", "testpipe", PipeDirection.InOut)) {
    
                    Console.WriteLine("[client] Attemping to connect to pipe...");
                    pipeClient.Connect();
    
                    Console.WriteLine("[client] connected to pipe");
                    Console.WriteLine("[client] There are currently {0} pipe server instances open.",pipeClient.NumberOfServerInstances);
    
                    StreamWriter writer = new StreamWriter(pipeClient);
                    writer.AutoFlush = true;
                    StreamReader reader = new StreamReader(pipeClient);
    
                    String temp = "";
                    while (true) {
                        temp = Console.ReadLine();
    
                        //send to server
                        writer.WriteLine(temp);
    
                        pipeClient.WaitForPipeDrain();
    
                        //read from server
                        Console.WriteLine("[client] read message from server:"+reader.ReadLine());
    
                        if (temp == "EXIT") {
                            break;
                        }
                    }
                }
    
                Console.ReadLine();
            }
        }
    }
    PipeClient.cs

    这里需要注意,"."代表本机地址。如果需要到其他服务器,替换就好了。

  • 相关阅读:
    Delphi中 弹出框的用法
    VC++代码上传到VSS上 注意事项
    VC++ 屏蔽掉警告
    IIS LocalDB 登录失败
    SVN版本回滚实战
    Git常用命令图解
    C# 百度API地址坐标互相转换
    Quartz.NET浅谈一 : 简单Job使用(定时发送QQ邮件)
    发布自己的类库包到Nuget
    C# 常用日期取得
  • 原文地址:https://www.cnblogs.com/HDK2016/p/9840989.html
Copyright © 2011-2022 走看看