zoukankan      html  css  js  c++  java
  • 管道的基本用法

    有关管道的基本用法请看System.IO之使用管道在进程间通信 (System.IO.Pipes使用)

    本文介绍命名管道使用实例,文中例子是几个客户端都通过一台服务器获得新生成的int类型id。

    服务器端功能:当客户端请求一个新的id时,将现有id自增1,然后返回给客户端。

    服务器端实现:在程序启动时,启动n个线程,在每个线程中都声明一个NamedPipeServerStream的实例,并循环的 WaitForConnection(),将新的id写入到命名管道中,然后断开连接。在程序退出时释放NamedPipeServerStream实例

    如下代码实现: 

    001 using System;
    002 using System.Collections.Generic;
    003 using System.Linq;
    004 using System.Text;
    005  
    006  
    007 using System.IO;
    008 using System.IO.Pipes;
    009 using System.Threading;
    010  
    011 namespace IDServer
    012 {
    013     class Program
    014     {
    015         /// <summary>
    016         /// 命名管道名字
    017         /// </summary>
    018         private const string PIPE_NAME = "testNetworkPipe";
    019  
    020         //定义线程数,也是NamedPipeServerStream的允许最多的实例数
    021         private const int MAX_THREADS_COUNT = 3;
    022         private static volatile int _runingThreadCount = 0;
    023  
    024         private static volatile int _newId = 0;
    025  
    026         //实例数组
    027         private static NamedPipeServerStream[] _serverStreams;
    028  
    029         static void Main(string[] args)
    030         {
    031             _serverStreams = new NamedPipeServerStream[MAX_THREADS_COUNT];
    032  
    033             //在进程退出时释放所有NamedPipeServerStream实例
    034             AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
    035              
    036             //启动线程
    037             StartServers();
    038  
    039             Console.Read();
    040         }
    041  
    042         /// <summary>
    043         /// 在进程退出时释放命名管道
    044         /// </summary>
    045         /// <param name="sender"></param>
    046         /// <param name="e"></param>
    047         static void CurrentDomain_ProcessExit(object sender, EventArgs e)
    048         {
    049             if (_serverStreams != null)
    050             {
    051                 foreach (NamedPipeServerStream item in _serverStreams)
    052                 {
    053                     item.Dispose();
    054                 }
    055             }
    056         }
    057  
    058         /// <summary>
    059         /// 启动服务器端线程
    060         /// </summary>
    061         private static void StartServers()
    062         {
    063             for (int i = 0; i < MAX_THREADS_COUNT; i++)
    064             {
    065                 Thread thread = new Thread(new ThreadStart(StartNewIDServer));
    066                 thread.Start();
    067             }
    068         }
    069  
    070  
    071         /// <summary>
    072         /// 启动一个NamedPipeServerStream实例
    073         /// </summary>
    074         private static void StartNewIDServer()
    075         {
    076             NamedPipeServerStream stream = null;
    077             Console.WriteLine("start server in thread " + Thread.CurrentThread.ManagedThreadId);
    078  
    079             stream = _serverStreams[_runingThreadCount] = new NamedPipeServerStream(PIPE_NAME,
    080                  PipeDirection.InOut,
    081                  MAX_THREADS_COUNT,
    082                  PipeTransmissionMode.Message,
    083                  PipeOptions.None);
    084             int threadNo = _runingThreadCount;
    085             _runingThreadCount += 1;
    086  
    087             while (true)
    088             {
    089                 stream.WaitForConnection();
    090                 int newId = ++_newId;
    091  
    092                 byte[] bytes = BitConverter.GetBytes(newId);
    093                 stream.Write(bytes, 0, bytes.Length);
    094                 stream.Flush();
    095                 Console.Write("threadNo:" + Thread.CurrentThread.ManagedThreadId + "\r");
    096                 stream.Disconnect();
    097             }
    098         }
    099  
    100     }
    101 }

    客户端的功能是不断的发出获得新id的请求,并打印新id,在客户端可以配置服务端的服务器IP。

    如下代码:

    01 using System;
    02 using System.Collections.Generic;
    03 using System.Linq;
    04 using System.Text;
    05 using System.Threading;
    06  
    07 namespace IDClient
    08 {
    09     class Program
    10     {
    11         private const string PIPE_NAME = "testNetworkPipe";
    12  
    13         static void Main(string[] args)
    14         {
    15             Console.WriteLine("请输入任何字符回车开始执行程序..");
    16             Console.Read();
    17             do
    18             {
    19                 //内网服务器ip,必须是局域网
    20                 string serverName = "127.0.0.1";
    21                 //声明NamedPipeClientStream实例
    22                 using (var clientStream = new System.IO.Pipes.NamedPipeClientStream(serverName, PIPE_NAME))
    23                 {
    24                     //连接服务器
    25                     clientStream.Connect(1000);
    26                     //设置为消息读取模式
    27                     clientStream.ReadMode = System.IO.Pipes.PipeTransmissionMode.Message;
    28  
    29                     do
    30                     {
    31                         byte[] bytes = new byte[4];
    32                         clientStream.Read(bytes, 0, 4);
    33                         int val = BitConverter.ToInt32(bytes, 0);
    34                         Console.Write("NewID == " + val + "\r");
    35                     } while (!clientStream.IsMessageComplete);
    36                 }
    37  
    38                 Thread.Sleep(1);
    39             } while (true);
    40         }
    41     }
    42 }

    在sql server中就使用了命名管道在局域网内挂进程通讯。

    在声明NamedPipeServerStream实例是可以指定其实例个数,如果实例数超过这个数,就会抛出“所有管道范例都在使用中”的IO异常。

    本例不可以在实际项目中使用。

    程序源码下载

    相关随笔: .Net那点事儿系列:System.IO之windows文件操作
    .Net那点事儿系列:System.IO之Stream
    System.IO之内存映射文件共享内存
    System.IO之使用管道在进程间通信 (System.IO.Pipes使用)
    System.IO系列:局域网内多线程使用命名管道在进程之间通信实例


    请尊重作者的劳动,转载请保留链接 玉开的技术博客

  • 相关阅读:
    UV动画
    使用RampTexture实现BRDF效果
    使用RampTexture来控制diffuse shading
    Half Lambert
    Lamber算法 & SurfaceShader自定义光照
    What is _MainTex_ST ?
    C# Enum,Int,String的互相转换
    Plugins in Unity
    Mono在Full AOT模式下的限制
    雾化
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2132654.html
Copyright © 2011-2022 走看看