好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

管道的基本用法

管道的基本用法

有关管道的基本用法请看 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系列:局域网内多线程使用命名管道在进程之间通信实例

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

玉开的技术随笔推荐 Asp.Net 网站优化系列 Asp.Net 4.0 新特性 c#推荐随笔 SQL Server 2005 LINQ to SQL随笔 SQLite相关推荐 客户端Css+js+html 在.Net中使用Xml 其他推荐随笔

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于管道的基本用法的详细内容...

  阅读:36次