当前位置:   article > 正文

.net中的命名管道(NamedPipe)_cclinetnamedpipe openpipe

cclinetnamedpipe openpipe

最近尝试代码分离,减少主程序中的代码,将很多Form都独立成单独的exe,主程序跟这些小程序间的通信就使用命名管道在进行。

之前运用过命名管道,但是是直接使用win32 api实现的,并且一直有问题,比如说有时候接收信息的阻塞被释放,但是又收不到任何东西。之前使用vs2005进行开发的,后来发现vs2010直接将命名管道封装成了类,就尝试使用了,发现比之前使用api时要顺手的多。

引用using System.IO.Pipes;这个命名空间,在vs2005中是没有此命名空间的,所以我将开发环境全部升级到了vs2010,还好升级比较方便。

我使用的情景都是阻塞式的,就是主程序调出某个exe后,主程序是无法运行的,必要等那个exe中程序执行完,或者关掉exe后,主程序才能响应。当然,如果需要做成非阻塞式的也是可以的,用线程或回调就行了。

vs2010自带的命名管道的类是分成服务器端跟客户端两个,有点类似使用soket的感觉,并且跟win32 api的方式也感觉不一样。win32 api的方式更像两边是对称的。

我封装了一个类,让软件调用的时候尽量的统一,不去区分服务器、客户端什么的。

下面是代码,注释写的应该也比较清楚。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.IO.Pipes;
  6. using System.Security.Principal;
  7. using System.Threading;
  8. using System.Diagnostics;
  9. namespace pipe
  10. {
  11. public class NamedPipe : IDisposable {
  12. string err = "";
  13. NamedPipeServerStream _pipeServer = null;
  14. NamedPipeClientStream _pipeClient = null;
  15. /// <summary>
  16. /// 初始化管道。每个进程发送与接收信息是两个管道进行通信。
  17. /// 两个进程使用的管道名是相对的
  18. /// 进程1使用的接收管道就是进程2使用的发送管道。进程2使用的发送管道就是进程1使用的接收管道。
  19. /// </summary>
  20. /// <param name="server">监听管道的名称</param>
  21. /// <param name="client">发送管道名称</param>
  22. public NamedPipe(string server, string client)
  23. {
  24. try {
  25. _pipeServer = new NamedPipeServerStream(server, PipeDirection.InOut, 10);
  26. _pipeClient = new NamedPipeClientStream(".", client, PipeDirection.InOut);
  27. }
  28. catch (Exception ex) {
  29. err = ex.Message;
  30. }
  31. }
  32. public bool openExe(string path) {
  33. Process p = new Process();
  34. try
  35. {
  36. p.StartInfo.FileName = path;
  37. p.StartInfo.UseShellExecute = false;
  38. p.StartInfo.RedirectStandardInput = true;
  39. p.StartInfo.CreateNoWindow = true;
  40. p.StartInfo.RedirectStandardOutput = true;
  41. p.StartInfo.RedirectStandardError = true;
  42. p.Start();
  43. return true;
  44. }
  45. catch (Exception ex)
  46. {
  47. err = ex.Message;
  48. return false;
  49. }
  50. finally {
  51. p.Close();
  52. p.Dispose();
  53. }
  54. }
  55. /// <summary>
  56. /// 读取错误信息
  57. /// </summary>
  58. /// <returns></returns>
  59. public string Err() {
  60. string s;
  61. s = err;
  62. err = "";
  63. return s;
  64. }
  65. /// <summary>
  66. /// 从管道中读取内容(阻塞式)
  67. /// </summary>
  68. /// <returns></returns>
  69. public string read()
  70. {
  71. try
  72. {
  73. if (!_pipeServer.IsConnected)
  74. {
  75. _pipeServer.WaitForConnection();
  76. }
  77. string str = "";
  78. StreamReader sr = new StreamReader(_pipeServer);
  79. while (_pipeServer.CanRead && (null != (str = sr.ReadLine())))
  80. {
  81. Thread.Sleep(50);
  82. return str;
  83. }
  84. return str;
  85. }
  86. catch (Exception ex)
  87. {
  88. err = ex.Message;
  89. return "";
  90. }
  91. }
  92. /// <summary>
  93. /// 往管道中写入内容
  94. /// </summary>
  95. /// <param name="s">写入的内容</param>
  96. public bool send(string s)
  97. {
  98. try
  99. {
  100. if (!_pipeClient.IsConnected)
  101. {
  102. _pipeClient.Connect();
  103. }
  104. StreamWriter sw = new StreamWriter(_pipeClient);
  105. sw.WriteLine(s);
  106. sw.Flush();
  107. return true;
  108. }
  109. catch (Exception ex)
  110. {
  111. err = ex.Message;
  112. return false;
  113. }
  114. }
  115. #region IDisposable 成员
  116. bool _disposed = false;
  117. public void Dispose()
  118. {
  119. try
  120. {
  121. if (!_disposed && _pipeServer != null)
  122. {
  123. _pipeServer.Close();
  124. _pipeServer.Dispose();
  125. }
  126. if (!_disposed && _pipeClient != null)
  127. {
  128. _pipeClient.Close();
  129. _pipeClient.Dispose();
  130. }
  131. _disposed = true;
  132. }
  133. catch (Exception ex)
  134. {
  135. err = ex.Message;
  136. }
  137. }
  138. #endregion
  139. }
  140. }

其实命名管道功能很强大,这里列举的只是在同一个电脑中两个进程间的通信,它甚至可以实现网络间的进程的通信,功能强大带来的开销以及效率肯定就是不太友好的,下一步准备来看看匿名管道,可能会更加符合我的应用场景。



声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号