The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Channels \ SocketStream

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //==========================================================================
  16. // File: SocketStream.cs
  17. //
  18. // Summary: Stream used for reading from a socket by remoting channels.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.IO;
  23. using System.Runtime.Remoting;
  24. using System.Net;
  25. using System.Net.Sockets;
  26. namespace System.Runtime.Remoting.Channels
  27. {
  28.    
  29.     // Basically the same as NetworkStream, but adds support for timeouts.
  30.     internal sealed class SocketStream : Stream
  31.     {
  32.         private Socket _socket;
  33.         private int _timeout = 0;
  34.         // throw timout exception if a read takes longer than this many milliseconds
  35.         // as per http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b201213
  36.         // we shouldn't write more than 64K synchronously to a socket
  37.         const int maxSocketWrite = 64 * 1024;
  38.         // 64k
  39.         const int maxSocketRead = 4 * 1024 * 1024;
  40.         // 4 MB
  41.        
  42.         public SocketStream(Socket socket)
  43.         {
  44.             if (socket == null)
  45.                 throw new ArgumentNullException("socket");
  46.            
  47.             _socket = socket;
  48.         }
  49.         // SocketStream
  50.        
  51.         // Stream implementation
  52.        
  53.         public override bool CanRead {
  54.             get { return true; }
  55.         }
  56.         public override bool CanSeek {
  57.             get { return false; }
  58.         }
  59.         public override bool CanWrite {
  60.             get { return true; }
  61.         }
  62.        
  63.         public override long Length {
  64.             get {
  65.                 throw new NotSupportedException();
  66.             }
  67.         }
  68.        
  69.         public override long Position {
  70.             get {
  71.                 throw new NotSupportedException();
  72.             }
  73.             set {
  74.                 throw new NotSupportedException();
  75.             }
  76.         }
  77.         // Position
  78.         public override long Seek(long offset, SeekOrigin origin)
  79.         {
  80.             throw new NotSupportedException();
  81.         }
  82.        
  83.         public override int Read(byte[] buffer, int offset, int size)
  84.         {
  85.            
  86.             if (_timeout <= 0) {
  87.                 return _socket.Receive(buffer, offset, Math.Min(size, maxSocketRead), SocketFlags.None);
  88.             }
  89.             else {
  90.                 IAsyncResult ar = _socket.BeginReceive(buffer, offset, Math.Min(size, maxSocketRead), SocketFlags.None, null, null);
  91.                 if (_timeout > 0 && !ar.IsCompleted) {
  92.                     ar.AsyncWaitHandle.WaitOne(_timeout, false);
  93.                     if (!ar.IsCompleted)
  94.                         throw new RemotingTimeoutException();
  95.                    
  96.                 }
  97.                 return _socket.EndReceive(ar);
  98.             }
  99.         }
  100.         // Read
  101.         public override void Write(byte[] buffer, int offset, int count)
  102.         {
  103.             int bytesToWrite = count;
  104.            
  105.             while (bytesToWrite > 0) {
  106.                 count = Math.Min(bytesToWrite, maxSocketWrite);
  107.                 _socket.Send(buffer, offset, count, SocketFlags.None);
  108.                 bytesToWrite -= count;
  109.                 offset += count;
  110.             }
  111.         }
  112.         // Write
  113.         protected override void Dispose(bool disposing)
  114.         {
  115.             try {
  116.                 if (disposing)
  117.                     _socket.Close();
  118.             }
  119.             finally {
  120.                 base.Dispose(disposing);
  121.             }
  122.         }
  123.        
  124.         public override void Flush()
  125.         {
  126.         }
  127.        
  128.        
  129.         public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  130.         {
  131.             IAsyncResult asyncResult = _socket.BeginReceive(buffer, offset, Math.Min(size, maxSocketRead), SocketFlags.None, callback, state);
  132.            
  133.             return asyncResult;
  134.         }
  135.         // BeginRead
  136.        
  137.         public override int EndRead(IAsyncResult asyncResult)
  138.         {
  139.             return _socket.EndReceive(asyncResult);
  140.         }
  141.         // EndRead
  142.        
  143.         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  144.         {
  145.             IAsyncResult asyncResult = _socket.BeginSend(buffer, offset, size, SocketFlags.None, callback, state);
  146.            
  147.             return asyncResult;
  148.         }
  149.         // BeginWrite
  150.        
  151.         public override void EndWrite(IAsyncResult asyncResult)
  152.         {
  153.             _socket.EndSend(asyncResult);
  154.         }
  155.         // EndWrite
  156.        
  157.         public override void SetLength(long value)
  158.         {
  159.             throw new NotSupportedException();
  160.         }
  161.        
  162.     }
  163.     // class SocketStream
  164. }
  165. // namespace System.Runtime.Remoting.Channels

Developer Fusion