Advertisement
Guest User

Untitled

a guest
Mar 30th, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.07 KB | None | 0 0
  1. public class PipeClient : IDisposable
  2. {
  3. private readonly string _pipeName;
  4. private NamedPipeClientStream _pipeStream;
  5. private StreamReader _streamReader;
  6. private byte[] _buffer;
  7. private object _pipeState = new object();
  8.  
  9. public event MessageRecievedHandler OnMessageRecieved;
  10.  
  11. /// <summary>
  12. /// Gets the underlying <c>PipeStream</c> object.
  13. /// </summary>
  14. public NamedPipeClientStream PipeStream { get { return _pipeStream; } }
  15.  
  16. /// <summary>
  17. /// Gets a value indicating whether the <see cref="PipeStream"/> object is connected or not.
  18. /// </summary>
  19. public bool IsConnected { get { return _pipeStream.IsConnected; } }
  20.  
  21. /// <summary>
  22. /// Main constructor.
  23. /// </summary>
  24. /// <param name="pipeName">The name of the channel being created.</param>
  25. public PipeClient(string pipeName)
  26. {
  27. if (String.IsNullOrEmpty(pipeName))
  28. {
  29. throw new IOException("Null or empty pipe name");
  30. }
  31. else
  32. {
  33. this._pipeName = pipeName;
  34. }
  35. }
  36.  
  37. public bool ConnectAndWaitForMessage()
  38. {
  39. if (_pipeStream != null) return false;
  40. try
  41. {
  42. _pipeStream = new NamedPipeClientStream(".", this._pipeName, PipeDirection.In, PipeOptions.Asynchronous);
  43. _pipeStream.Connect();
  44. _buffer = new Byte[255];
  45. _pipeStream.BeginRead(_buffer, 0, _buffer.Length, PipeReadCallback, _pipeState);
  46. return true;
  47. }
  48. catch
  49. {
  50. //TODO
  51. return false;
  52. }
  53. }
  54.  
  55. private void PipeReadCallback(IAsyncResult ar)
  56. {
  57. int bytesRead = 0;
  58.  
  59. // if port serial is open and..
  60. if (_pipeStream.IsConnected)
  61. {
  62. // the stream can read then..
  63. if (_pipeStream.CanRead)
  64. {
  65. // wait for asynchronous read to be completed
  66. bytesRead = _pipeStream.EndRead(ar);
  67. //_pipeStream.Flush();
  68. }
  69. }
  70.  
  71. if (bytesRead > 0)
  72. {
  73. if (OnMessageRecieved != null)
  74. OnMessageRecieved(this, new MessageRecievedEventArgs(_buffer));
  75. }
  76. }
  77.  
  78.  
  79. public void Dispose()
  80. {
  81. throw new NotImplementedException();
  82. }
  83.  
  84. }
  85.  
  86. public delegate void ClientConnectedEventHandler(object sender, PipeConnection connection);
  87.  
  88. /// <summary>
  89. /// The class provides server-side tools for client-server interaction by named pipes.
  90. /// </summary>
  91. public class PipeServer
  92. {
  93. private readonly string _pipeName;
  94. private NamedPipeServerStream _pipeStream;
  95. private bool isListeningToClients = false;
  96. private List<PipeConnection> connectionsList;
  97.  
  98. public event ClientConnectedEventHandler OnClientConnected;
  99.  
  100. /// <summary>
  101. /// Returns the number of clients connected.
  102. /// </summary>
  103. public int ClientsCount
  104. {
  105. get
  106. {
  107. return connectionsList.Count;
  108. }
  109. }
  110.  
  111. /// <summary>
  112. /// Creates a new instance of the class PipeServer.
  113. /// </summary>
  114. /// <param name="pipeName">Name of the created named pipe.</param>
  115. public PipeServer(string pipeName)
  116. {
  117. if (String.IsNullOrEmpty(pipeName))
  118. {
  119. throw new IOException("Null or empty pipe name");
  120. }
  121. else
  122. {
  123. this._pipeName = pipeName;
  124. this.isListeningToClients = true;
  125. this.connectionsList = new List<PipeConnection>();
  126. ListenForPipeClients();
  127. }
  128. }
  129.  
  130. /// <summary>
  131. /// Sends a message to all connected clients. Updates the list of connected.
  132. /// </summary>
  133. /// <param name="message">Text message to send.</param>
  134. public void SendMessage(string message)
  135. {
  136. if (!this.isListeningToClients || connectionsList.Count == 0)
  137. return;
  138.  
  139. List<PipeConnection> connListTmp = new List<PipeConnection>();
  140. byte[] _buffer = Encoding.UTF8.GetBytes(message);
  141. foreach (PipeConnection conn in connectionsList)
  142. {
  143. if (conn.IsConnected && conn.CanWrite)
  144. {
  145. try
  146. {
  147. connListTmp.Add(conn);
  148. conn.BaseStream.BeginWrite(_buffer, 0, _buffer.Length, new AsyncCallback(OnMessageAsyncSend), conn.BaseStream);
  149. }
  150. catch (Exception e)
  151. {
  152. Console.WriteLine("Error occures: {0}.", e.Message);
  153. }
  154. }
  155. else conn.Close();
  156. }
  157. connectionsList = connListTmp;
  158. }
  159.  
  160.  
  161. /// <summary>
  162. /// Create new NamedPipeServerStream for listening to pipe client connection
  163. /// </summary>
  164. private void ListenForPipeClients()
  165. {
  166. if (!this.isListeningToClients)
  167. return;
  168.  
  169. try
  170. {
  171. if (_pipeStream == null)
  172. _pipeStream = new NamedPipeServerStream(_pipeName, PipeDirection.Out, 5, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
  173. IAsyncResult result = _pipeStream.BeginWaitForConnection(OnPipeConnected, _pipeStream);
  174. Console.WriteLine("Waiting for client connection...");
  175. }
  176. catch (ObjectDisposedException)
  177. {
  178. //// Catch ObjectDisposedException if server was stopped. Then do nothing.
  179. }
  180. catch (Exception e)
  181. {
  182. Console.WriteLine("Error occures: {0}. Restart pipe server...", e.Message);
  183. //ListenForPipeClients();
  184. }
  185. }
  186.  
  187. /// <summary>
  188. /// Async callback on client connected action
  189. /// </summary>
  190. /// <param name="asyncResult">Async result</param>
  191. private void OnPipeConnected(IAsyncResult asyncResult)
  192. {
  193. using (var conn = (NamedPipeServerStream)asyncResult.AsyncState)
  194. {
  195. try
  196. {
  197. conn.EndWaitForConnection(asyncResult);
  198. Console.WriteLine("Client connected.");
  199. PipeConnection clientConnection = new PipeConnection(conn);
  200. connectionsList.Add(clientConnection);
  201. if (OnClientConnected != null)
  202. OnClientConnected(this, clientConnection);
  203. }
  204. catch (Exception e)
  205. {
  206. Console.WriteLine(e.Message);
  207. }
  208. }
  209.  
  210. ListenForPipeClients();
  211. }
  212.  
  213. private void OnMessageAsyncSend(IAsyncResult ar)
  214. {
  215. using (var conn = (NamedPipeServerStream)ar.AsyncState)
  216. {
  217. try
  218. {
  219. conn.EndRead(ar);
  220. conn.Flush();
  221. Console.WriteLine("Message sent successfully!");
  222. }
  223. catch (Exception e)
  224. {
  225. Console.WriteLine("Error occures: {0}.", e.Message);
  226. }
  227. }
  228. }
  229.  
  230. public void StopListening()
  231. {
  232. if (!this.isListeningToClients)
  233. return;
  234.  
  235. this.isListeningToClients = false;
  236. Console.WriteLine("Close all active connections...");
  237. if (connectionsList.Count > 0)
  238. {
  239. foreach (PipeConnection conn in connectionsList)
  240. {
  241. if (conn.IsConnected)
  242. conn.Close();
  243. }
  244. }
  245. }
  246. }
  247.  
  248. public class PipeConnection
  249. {
  250. /// <summary>
  251. /// Gets the connection's unique identifier.
  252. /// </summary>
  253. public readonly int Id;
  254.  
  255. /// <summary>
  256. /// Gets the connection's name.
  257. /// </summary>
  258. //public string Name { get; }
  259.  
  260. /// <summary>
  261. /// Gets the underlying <c>PipeStream</c> object.
  262. /// </summary>
  263. public PipeStream BaseStream { get; private set; }
  264.  
  265. /// <summary>
  266. /// Gets a value indicating whether the <see cref="BaseStream"/> object is connected or not.
  267. /// </summary>
  268. /// <returns>
  269. /// <c>true</c> if the <see cref="BaseStream"/> object is connected; otherwise, <c>false</c>.
  270. /// </returns>
  271. public bool IsConnected
  272. {
  273. get { return BaseStream.IsConnected; }
  274. }
  275.  
  276. /// <summary>
  277. /// Gets a value indicating whether the current stream supports read operations.
  278. /// </summary>
  279. /// <returns>
  280. /// <c>true</c> if the stream supports read operations; otherwise, <c>false</c>.
  281. /// </returns>
  282. public bool CanRead
  283. {
  284. get { return BaseStream.CanRead; }
  285. }
  286.  
  287. /// <summary>
  288. /// Gets a value indicating whether the current stream supports write operations.
  289. /// </summary>
  290. /// <returns>
  291. /// <c>true</c> if the stream supports write operations; otherwise, <c>false</c>.
  292. /// </returns>
  293. public bool CanWrite
  294. {
  295. get { return BaseStream.CanWrite; }
  296. }
  297.  
  298. /// <summary>
  299. /// Constructs a new <c>PipeConnection</c> object that reads from and writes to the given <paramref name="stream"/>.
  300. /// </summary>
  301. /// <param name="stream">Stream to read from and write to</param>
  302. public PipeConnection(PipeStream stream)
  303. {
  304. BaseStream = stream;
  305. }
  306.  
  307. /// <summary>
  308. /// Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
  309. /// </summary>
  310. public void Close()
  311. {
  312. BaseStream.Close();
  313. BaseStream.Dispose();
  314. }
  315. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement