NetworkStream.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //
  2. // System.Net.Sockets.NetworkStream.cs
  3. //
  4. // Author:
  5. // Miguel de Icaza ([email protected])
  6. //
  7. // (C) 2002 Ximian, Inc. http://www.ximian.com
  8. //
  9. using System.IO;
  10. namespace System.Net.Sockets
  11. {
  12. public class NetworkStream : Stream, IDisposable {
  13. FileAccess access;
  14. Socket socket;
  15. bool owns_socket;
  16. bool readable, writeable;
  17. bool disposed = false;
  18. public NetworkStream (Socket socket)
  19. : this (socket, FileAccess.ReadWrite, false)
  20. {
  21. }
  22. public NetworkStream (Socket socket, bool owns_socket)
  23. : this (socket, FileAccess.ReadWrite, owns_socket)
  24. {
  25. }
  26. public NetworkStream (Socket socket, FileAccess access)
  27. : this (socket, access, false)
  28. {
  29. }
  30. public NetworkStream (Socket socket, FileAccess access, bool owns_socket)
  31. {
  32. if (socket == null)
  33. throw new ArgumentNullException ();
  34. if (!socket.Connected)
  35. throw new ArgumentException ("Not connected", "socket");
  36. if (socket.SocketType != SocketType.Stream)
  37. throw new ArgumentException ("Socket is not of type Stream", "socket");
  38. if (!socket.Blocking)
  39. throw new IOException ();
  40. this.socket = socket;
  41. this.owns_socket = owns_socket;
  42. this.access = access;
  43. readable = CanRead;
  44. writeable = CanWrite;
  45. }
  46. public override bool CanRead {
  47. get {
  48. return access == FileAccess.ReadWrite || access == FileAccess.Read;
  49. }
  50. }
  51. public override bool CanSeek {
  52. get {
  53. // network sockets cant seek.
  54. return false;
  55. }
  56. }
  57. public override bool CanWrite {
  58. get {
  59. return access == FileAccess.ReadWrite || access == FileAccess.Write;
  60. }
  61. }
  62. public virtual bool DataAvailable {
  63. get {
  64. try {
  65. return socket.Available > 0;
  66. } finally {
  67. CheckDisposed ();
  68. }
  69. }
  70. }
  71. public override long Length {
  72. get {
  73. // Network sockets always throw an exception
  74. throw new NotSupportedException ();
  75. }
  76. }
  77. public override long Position {
  78. get {
  79. // Network sockets always throw an exception
  80. throw new NotSupportedException ();
  81. }
  82. set {
  83. // Network sockets always throw an exception
  84. throw new NotSupportedException ();
  85. }
  86. }
  87. protected bool Readable {
  88. get {
  89. return readable;
  90. }
  91. set {
  92. readable = value;
  93. }
  94. }
  95. protected Socket Socket {
  96. get {
  97. return socket;
  98. }
  99. }
  100. protected bool Writeable {
  101. get {
  102. return writeable;
  103. }
  104. set {
  105. writeable = value;
  106. }
  107. }
  108. public override IAsyncResult BeginRead (byte [] buffer, int offset, int size,
  109. AsyncCallback callback, object state)
  110. {
  111. try {
  112. IAsyncResult retval;
  113. if (buffer == null)
  114. throw new ArgumentNullException ();
  115. int len = buffer.Length;
  116. if (offset >= len || size != len)
  117. throw new ArgumentOutOfRangeException ();
  118. try {
  119. retval = socket.BeginReceive (buffer, offset, size, 0, callback, state);
  120. } catch {
  121. throw new IOException ("BeginReceive failure");
  122. }
  123. return retval;
  124. } finally {
  125. CheckDisposed ();
  126. }
  127. }
  128. public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size,
  129. AsyncCallback callback, object state)
  130. {
  131. try {
  132. IAsyncResult retval;
  133. if (buffer == null)
  134. throw new ArgumentNullException ();
  135. int len = buffer.Length;
  136. if (len < size)
  137. throw new ArgumentException ();
  138. try {
  139. retval = socket.BeginSend (buffer, offset, size, 0, callback, state);
  140. } catch {
  141. throw new IOException ("BeginWrite failure");
  142. }
  143. return retval;
  144. } finally {
  145. CheckDisposed ();
  146. }
  147. }
  148. ~NetworkStream ()
  149. {
  150. Dispose (false);
  151. }
  152. public override void Close ()
  153. {
  154. ((IDisposable) this).Dispose ();
  155. }
  156. protected virtual void Dispose (bool disposing)
  157. {
  158. if (disposed)
  159. return;
  160. disposed = true;
  161. if (owns_socket) {
  162. Socket s = socket;
  163. if (s != null)
  164. s.Close ();
  165. }
  166. socket = null;
  167. }
  168. public override int EndRead (IAsyncResult ar)
  169. {
  170. try {
  171. int res;
  172. if (ar == null)
  173. throw new ArgumentNullException ();
  174. try {
  175. res = socket.EndReceive (ar);
  176. } catch {
  177. throw new IOException ("EndRead failure");
  178. }
  179. return res;
  180. } finally {
  181. CheckDisposed ();
  182. }
  183. }
  184. public override void EndWrite (IAsyncResult ar)
  185. {
  186. try {
  187. if (ar == null)
  188. throw new ArgumentNullException ();
  189. try {
  190. socket.EndSend (ar);
  191. } catch {
  192. throw new IOException ("EndWrite failure");
  193. }
  194. } finally {
  195. CheckDisposed ();
  196. }
  197. }
  198. public override void Flush ()
  199. {
  200. // network streams are non-buffered, this is a no-op
  201. }
  202. void IDisposable.Dispose ()
  203. {
  204. Dispose (true);
  205. GC.SuppressFinalize (this);
  206. }
  207. public override int Read (byte [] buffer, int offset, int size)
  208. {
  209. try {
  210. int res;
  211. if (buffer == null)
  212. throw new ArgumentNullException ();
  213. if (buffer.Length < size)
  214. throw new ArgumentException ();
  215. try {
  216. res = socket.Receive (buffer, offset, size, 0);
  217. } catch {
  218. throw new IOException ("Read failure");
  219. }
  220. return res;
  221. } finally {
  222. CheckDisposed ();
  223. }
  224. }
  225. public override long Seek (long offset, SeekOrigin origin)
  226. {
  227. // NetworkStream objects do not support seeking.
  228. throw new NotSupportedException ();
  229. }
  230. public override void SetLength (long value)
  231. {
  232. // NetworkStream objects do not support SetLength
  233. throw new NotSupportedException ();
  234. }
  235. public override void Write (byte [] buffer, int offset, int size)
  236. {
  237. try {
  238. if (buffer == null)
  239. throw new ArgumentNullException ();
  240. if (buffer.Length < size)
  241. throw new ArgumentException ();
  242. try {
  243. socket.Send (buffer, offset, size, 0);
  244. } catch {
  245. throw new IOException ("Write failure");
  246. }
  247. } finally {
  248. CheckDisposed ();
  249. }
  250. }
  251. private void CheckDisposed ()
  252. {
  253. if (disposed)
  254. throw new ObjectDisposedException (GetType().FullName);
  255. }
  256. }
  257. }