PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/source/library/Interlace/ReactorCore/StreamConnection.cs

https://bitbucket.org/VahidN/interlace
C# | 223 lines | 156 code | 40 blank | 27 comment | 8 complexity | c5cdf7a3b2918e53a8f2da6eff75d533 MD5 | raw file
  1. #region Using Directives and Copyright Notice
  2. // Copyright (c) 2007-2010, Computer Consultancy Pty Ltd
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above copyright
  10. // notice, this list of conditions and the following disclaimer in the
  11. // documentation and/or other materials provided with the distribution.
  12. // * Neither the name of the Computer Consultancy Pty Ltd nor the
  13. // names of its contributors may be used to endorse or promote products
  14. // derived from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. // ARE DISCLAIMED. IN NO EVENT SHALL COMPUTER CONSULTANCY PTY LTD BE LIABLE
  20. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  26. // DAMAGE.
  27. using System;
  28. using System.Collections.Generic;
  29. using System.IO;
  30. using System.Net;
  31. using System.Net.Sockets;
  32. using System.Text;
  33. #endregion
  34. namespace Interlace.ReactorCore
  35. {
  36. public class StreamConnection : Connection
  37. {
  38. Stream _readStream = null;
  39. Stream _writeStream = null;
  40. internal StreamConnection(IReactor reactor, Protocol protocol)
  41. : base(reactor, protocol)
  42. {
  43. }
  44. internal void StartConnection(Stream readStream, Stream writeStream, int receiveBufferSize)
  45. {
  46. if (_isConnected) throw new InvalidOperationException(
  47. "An attempt was made to connect an already connected connection.");
  48. _readStream = readStream;
  49. _writeStream = writeStream;
  50. StartConnection(receiveBufferSize);
  51. }
  52. protected override void CloseSocketWhileIgnoringErrors()
  53. {
  54. if (!_isConnected) return;
  55. try
  56. {
  57. _readStream.Close();
  58. }
  59. catch (ObjectDisposedException)
  60. {
  61. // Ignore.
  62. }
  63. try
  64. {
  65. _writeStream.Close();
  66. }
  67. catch (ObjectDisposedException)
  68. {
  69. // Ignore.
  70. }
  71. }
  72. public IPEndPoint RemoteEndPoint
  73. {
  74. get { return null; }
  75. }
  76. protected override void ContinueReceive()
  77. {
  78. IAsyncResult result;
  79. try
  80. {
  81. result = _readStream.BeginRead(_receiveBuffer, 0,
  82. _receiveBuffer.Length, null, null);
  83. }
  84. catch (IOException ex)
  85. {
  86. HandleSocketException(ex);
  87. return;
  88. }
  89. catch (ObjectDisposedException ex)
  90. {
  91. HandleSocketClosed(ex);
  92. return;
  93. }
  94. _reactor.AddResult(result, ReceiveCompleted);
  95. }
  96. void ReceiveCompleted(IAsyncResult result, object state)
  97. {
  98. int bytesReceived;
  99. try
  100. {
  101. bytesReceived = _readStream.EndRead(result);
  102. }
  103. catch (IOException ex)
  104. {
  105. HandleSocketException(ex);
  106. return;
  107. }
  108. catch (ObjectDisposedException ex)
  109. {
  110. HandleSocketClosed(ex);
  111. return;
  112. }
  113. if (bytesReceived == 0)
  114. {
  115. HandleSocketReadFailed();
  116. return;
  117. }
  118. try
  119. {
  120. _protocol.DataReceived(null, _receiveBuffer, 0, bytesReceived);
  121. }
  122. catch (Exception ex)
  123. {
  124. HandleProtocolException(ex);
  125. }
  126. ContinueReceive();
  127. }
  128. protected override void ContinueSend()
  129. {
  130. IAsyncResult result;
  131. try
  132. {
  133. result = _writeStream.BeginWrite(_transmitBuffer.Data.Array, _transmitBuffer.Data.Offset,
  134. _transmitBuffer.Data.Count, null, _transmitBuffer.Data.Count);
  135. }
  136. catch (IOException ex)
  137. {
  138. HandleSocketException(ex);
  139. return;
  140. }
  141. catch (ObjectDisposedException ex)
  142. {
  143. HandleSocketClosed(ex);
  144. return;
  145. }
  146. _reactor.AddResult(result, SendCompleted);
  147. }
  148. void SendCompleted(IAsyncResult result, object state)
  149. {
  150. int bytesSent = (int)result.AsyncState;
  151. try
  152. {
  153. _writeStream.EndWrite(result);
  154. _writeStream.Flush();
  155. }
  156. catch (IOException ex)
  157. {
  158. HandleSocketException(ex);
  159. return;
  160. }
  161. catch (ObjectDisposedException ex)
  162. {
  163. HandleSocketClosed(ex);
  164. return;
  165. }
  166. if (bytesSent == 0)
  167. {
  168. HandleSocketReadFailed();
  169. return;
  170. }
  171. _transmitBuffer = _transmitBuffer.WithConsumedBytes(bytesSent);
  172. if (_transmitBuffer.Data.Count == 0)
  173. {
  174. _isTransmitting = false;
  175. KickSendQueue();
  176. }
  177. else
  178. {
  179. ContinueSend();
  180. }
  181. }
  182. }
  183. }