管道的基本用法
有关管道的基本用法请看 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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息