The Labs \ Source Viewer \ SSCLI \ System.Net.Sockets \ NetworkStream

  1. //------------------------------------------------------------------------------
  2. // <copyright file="NetworkStream.cs" company="Microsoft">
  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. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Net.Sockets
  16. {
  17.     using System.IO;
  18.     using System.Runtime.InteropServices;
  19.     using System.Threading;
  20.     using System.Security.Permissions;
  21.    
  22.     /// <devdoc>
  23.     /// <para>
  24.     /// Provides the underlying stream of data for network access.
  25.     /// </para>
  26.     /// </devdoc>
  27.     public class NetworkStream : Stream
  28.     {
  29.         /// <devdoc>
  30.         /// <para>
  31.         /// Used by the class to hold the underlying socket the stream uses.
  32.         /// </para>
  33.         /// </devdoc>
  34.         private Socket m_StreamSocket;
  35.        
  36.         /// <devdoc>
  37.         /// <para>
  38.         /// Used by the class to indicate that the stream is m_Readable.
  39.         /// </para>
  40.         /// </devdoc>
  41.         private bool m_Readable;
  42.        
  43.         /// <devdoc>
  44.         /// <para>
  45.         /// Used by the class to indicate that the stream is writable.
  46.         /// </para>
  47.         /// </devdoc>
  48.         private bool m_Writeable;
  49.        
  50.         private bool m_OwnsSocket;
  51.        
  52.         /// <devdoc>
  53.         /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> without initalization.</para>
  54.         /// </devdoc>
  55.         internal NetworkStream()
  56.         {
  57.             m_OwnsSocket = true;
  58.         }
  59.        
  60.        
  61.         // Can be constructed directly out of a socket
  62.         /// <devdoc>
  63.         /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> class for the specified <see cref='System.Net.Sockets.Socket'/>.</para>
  64.         /// </devdoc>
  65.         public NetworkStream(Socket socket)
  66.         {
  67.             #if DEBUG
  68.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  69.                 #endif
  70.                 if (socket == null) {
  71.                     throw new ArgumentNullException("socket");
  72.                 }
  73.                 InitNetworkStream(socket, FileAccess.ReadWrite);
  74.                 #if DEBUG
  75.             }
  76.             #endif
  77.         }
  78.        
  79.         //UEUE (see FileStream)
  80.         // ownsHandle: true if the file handle will be owned by this NetworkStream instance; otherwise, false.
  81.         public NetworkStream(Socket socket, bool ownsSocket)
  82.         {
  83.             #if DEBUG
  84.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  85.                 #endif
  86.                 if (socket == null) {
  87.                     throw new ArgumentNullException("socket");
  88.                 }
  89.                 InitNetworkStream(socket, FileAccess.ReadWrite);
  90.                 m_OwnsSocket = ownsSocket;
  91.                 #if DEBUG
  92.             }
  93.             #endif
  94.         }
  95.        
  96.         internal NetworkStream(NetworkStream networkStream, bool ownsSocket)
  97.         {
  98.             Socket socket = networkStream.Socket;
  99.             if (socket == null) {
  100.                 throw new ArgumentNullException("networkStream");
  101.             }
  102.             InitNetworkStream(socket, FileAccess.ReadWrite);
  103.             m_OwnsSocket = ownsSocket;
  104.         }
  105.        
  106.         // Create with a socket and access mode
  107.         /// <devdoc>
  108.         /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> class for the specified <see cref='System.Net.Sockets.Socket'/> with the specified access rights.</para>
  109.         /// </devdoc>
  110.         public NetworkStream(Socket socket, FileAccess access)
  111.         {
  112.             #if DEBUG
  113.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  114.                 #endif
  115.                 if (socket == null) {
  116.                     throw new ArgumentNullException("socket");
  117.                 }
  118.                 InitNetworkStream(socket, access);
  119.                 #if DEBUG
  120.             }
  121.             #endif
  122.         }
  123.         public NetworkStream(Socket socket, FileAccess access, bool ownsSocket)
  124.         {
  125.             #if DEBUG
  126.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  127.                 #endif
  128.                 if (socket == null) {
  129.                     throw new ArgumentNullException("socket");
  130.                 }
  131.                 InitNetworkStream(socket, access);
  132.                 m_OwnsSocket = ownsSocket;
  133.                 #if DEBUG
  134.             }
  135.             #endif
  136.         }
  137.        
  138.         //
  139.         // Socket - provides access to socket for stream closing
  140.         //
  141.         protected Socket Socket {
  142.             get { return m_StreamSocket; }
  143.         }
  144.        
  145.         internal Socket InternalSocket {
  146.             get {
  147.                 Socket chkSocket = m_StreamSocket;
  148.                 if (m_CleanedUp || chkSocket == null) {
  149.                     throw new ObjectDisposedException(this.GetType().FullName);
  150.                 }
  151.                
  152.                 return chkSocket;
  153.             }
  154.         }
  155.        
  156.         internal void ConvertToNotSocketOwner()
  157.         {
  158.             m_OwnsSocket = false;
  159.             // Suppress for finialization still allow proceed the requests
  160.             GC.SuppressFinalize(this);
  161.         }
  162.        
  163.         /// <devdoc>
  164.         /// <para>
  165.         /// Used by the class to indicate that the stream is m_Readable.
  166.         /// </para>
  167.         /// </devdoc>
  168.         protected bool Readable {
  169.             get { return m_Readable; }
  170.             set { m_Readable = value; }
  171.         }
  172.        
  173.         /// <devdoc>
  174.         /// <para>
  175.         /// Used by the class to indicate that the stream is writable.
  176.         /// </para>
  177.         /// </devdoc>
  178.         protected bool Writeable {
  179.             get { return m_Writeable; }
  180.             set { m_Writeable = value; }
  181.         }
  182.        
  183.        
  184.         /// <devdoc>
  185.         /// <para>
  186.         /// Indicates that data can be read from the stream.
  187.         /// We return the readability of this stream. This is a read only property.
  188.         /// </para>
  189.         /// </devdoc>
  190.         public override bool CanRead {
  191.             get { return m_Readable; }
  192.         }
  193.        
  194.        
  195.         /// <devdoc>
  196.         /// <para>
  197.         /// Indicates that the stream can seek a specific location
  198.         /// in the stream. This property always returns <see langword='false'/>
  199.         /// .
  200.         /// </para>
  201.         /// </devdoc>
  202.         public override bool CanSeek {
  203.             get { return false; }
  204.         }
  205.        
  206.        
  207.         /// <devdoc>
  208.         /// <para>
  209.         /// Indicates that data can be written to the stream.
  210.         /// </para>
  211.         /// </devdoc>
  212.         public override bool CanWrite {
  213.             get { return m_Writeable; }
  214.         }
  215.        
  216.        
  217.         /// <devdoc>
  218.         /// <para>Indicates whether we can timeout</para>
  219.         /// </devdoc>
  220.         public override bool CanTimeout {
  221.                 // should we check for Connected state?
  222.             get { return true; }
  223.         }
  224.        
  225.        
  226.         /// <devdoc>
  227.         /// <para>Set/Get ReadTimeout, note of a strange behavior, 0 timeout == infinite for sockets,
  228.         /// so we map this to -1, and if you set 0, we cannot support it</para>
  229.         /// </devdoc>
  230.         public override int ReadTimeout {
  231.             get {
  232.                 #if DEBUG
  233.                 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  234.                     #endif
  235.                     int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
  236.                     if (timeout == 0) {
  237.                         return -1;
  238.                     }
  239.                     return timeout;
  240.                     #if DEBUG
  241.                 }
  242.                 #endif
  243.             }
  244.             set {
  245.                 #if DEBUG
  246.                 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  247.                     #endif
  248.                     if (value <= 0 && value != System.Threading.Timeout.Infinite) {
  249.                         throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero));
  250.                     }
  251.                     SetSocketTimeoutOption(SocketShutdown.Receive, value, false);
  252.                     #if DEBUG
  253.                 }
  254.                 #endif
  255.             }
  256.         }
  257.        
  258.         /// <devdoc>
  259.         /// <para>Set/Get WriteTimeout, note of a strange behavior, 0 timeout == infinite for sockets,
  260.         /// so we map this to -1, and if you set 0, we cannot support it</para>
  261.         /// </devdoc>
  262.         public override int WriteTimeout {
  263.             get {
  264.                 #if DEBUG
  265.                 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  266.                     #endif
  267.                     int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout);
  268.                     if (timeout == 0) {
  269.                         return -1;
  270.                     }
  271.                     return timeout;
  272.                     #if DEBUG
  273.                 }
  274.                 #endif
  275.             }
  276.             set {
  277.                 #if DEBUG
  278.                 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  279.                     #endif
  280.                     if (value <= 0 && value != System.Threading.Timeout.Infinite) {
  281.                         throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero));
  282.                     }
  283.                     SetSocketTimeoutOption(SocketShutdown.Send, value, false);
  284.                     #if DEBUG
  285.                 }
  286.                 #endif
  287.             }
  288.         }
  289.        
  290.         /// <devdoc>
  291.         /// <para>
  292.         /// Indicates data is available on the stream to be read.
  293.         /// This property checks to see if at least one byte of data is currently available
  294.         /// </para>
  295.         /// </devdoc>
  296.         public virtual bool DataAvailable {
  297.             get {
  298.                 #if DEBUG
  299.                 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  300.                     #endif
  301.                     if (m_CleanedUp) {
  302.                         throw new ObjectDisposedException(this.GetType().FullName);
  303.                     }
  304.                    
  305.                     Socket chkStreamSocket = m_StreamSocket;
  306.                     if (chkStreamSocket == null) {
  307.                         throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  308.                     }
  309.                    
  310.                     // Ask the socket how many bytes are available. If it's
  311.                     // not zero, return true.
  312.                    
  313.                     return chkStreamSocket.Available != 0;
  314.                     #if DEBUG
  315.                 }
  316.                 #endif
  317.             }
  318.         }
  319.        
  320.        
  321.         /// <devdoc>
  322.         /// <para>
  323.         /// The length of data available on the stream. Always throws <see cref='NotSupportedException'/>.
  324.         /// </para>
  325.         /// </devdoc>
  326.         public override long Length {
  327.             get {
  328.                 throw new NotSupportedException(SR.GetString(SR.net_noseek));
  329.             }
  330.         }
  331.        
  332.         /// <devdoc>
  333.         /// <para>
  334.         /// Gets or sets the position in the stream. Always throws <see cref='NotSupportedException'/>.
  335.         /// </para>
  336.         /// </devdoc>
  337.         public override long Position {
  338.             get {
  339.                 throw new NotSupportedException(SR.GetString(SR.net_noseek));
  340.             }
  341.            
  342.             set {
  343.                 throw new NotSupportedException(SR.GetString(SR.net_noseek));
  344.             }
  345.         }
  346.        
  347.        
  348.         /// <devdoc>
  349.         /// <para>
  350.         /// Seeks a specific position in the stream. This method is not supported by the
  351.         /// <see cref='NetworkStream'/> class.
  352.         /// </para>
  353.         /// </devdoc>
  354.         public override long Seek(long offset, SeekOrigin origin)
  355.         {
  356.             throw new NotSupportedException(SR.GetString(SR.net_noseek));
  357.         }
  358.        
  359.        
  360. /*++
  361.             InitNetworkStream - initialize a network stream.
  362.             This is the common NetworkStream constructor, called whenever a
  363.             network stream is created. We validate the socket, set a few
  364.             options, and call our parent's initializer.
  365.             Input:
  366.                 S          - Socket to be used.
  367.                 Access      - Access type desired.
  368.             Returns:
  369.                 Nothing, but may throw an exception.
  370.         --*/       
  371.        
  372.         internal void InitNetworkStream(Socket socket, FileAccess Access)
  373.         {
  374.             //
  375.             // parameter validation
  376.             //
  377.             if (!socket.Blocking) {
  378.                 throw new IOException(SR.GetString(SR.net_sockets_blocking));
  379.             }
  380.             if (!socket.Connected) {
  381.                 throw new IOException(SR.GetString(SR.net_notconnected));
  382.             }
  383.             if (socket.SocketType != SocketType.Stream) {
  384.                 throw new IOException(SR.GetString(SR.net_notstream));
  385.             }
  386.            
  387.             m_StreamSocket = socket;
  388.            
  389.             switch (Access) {
  390.                 case FileAccess.Read:
  391.                     m_Readable = true;
  392.                     break;
  393.                 case FileAccess.Write:
  394.                     m_Writeable = true;
  395.                     break;
  396.                 case FileAccess.ReadWrite:
  397.                 default:
  398.                     // assume FileAccess.ReadWrite
  399.                     m_Readable = true;
  400.                     m_Writeable = true;
  401.                     break;
  402.             }
  403.            
  404.         }
  405.        
  406.        
  407.         internal bool Poll(int microSeconds, SelectMode mode)
  408.         {
  409.             if (m_CleanedUp) {
  410.                 throw new ObjectDisposedException(this.GetType().FullName);
  411.             }
  412.            
  413.             Socket chkStreamSocket = m_StreamSocket;
  414.             if (chkStreamSocket == null) {
  415.                 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  416.             }
  417.            
  418.             return chkStreamSocket.Poll(microSeconds, mode);
  419.         }
  420.        
  421.        
  422. /*++
  423.             Read - provide core Read functionality.
  424.             Provide core read functionality. All we do is call through to the
  425.             socket Receive functionality.
  426.             Input:
  427.                 Buffer  - Buffer to read into.
  428.                 Offset  - Offset into the buffer where we're to read.
  429.                 Count  - Number of bytes to read.
  430.             Returns:
  431.                 Number of bytes we read, or 0 if the socket is closed.
  432.         --*/       
  433.        
  434.         /// <devdoc>
  435.         /// <para>
  436.         /// Reads data from the stream.
  437.         /// </para>
  438.         /// </devdoc>
  439.         //UEUE
  440.         public override int Read(        [In(), Out()]
  441. byte[] buffer, int offset, int size)
  442.         {
  443.             #if DEBUG
  444.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
  445.                 #endif
  446.                 if (m_CleanedUp) {
  447.                     throw new ObjectDisposedException(this.GetType().FullName);
  448.                 }
  449.                 //
  450.                 // parameter validation
  451.                 //
  452.                 if (buffer == null) {
  453.                     throw new ArgumentNullException("buffer");
  454.                 }
  455.                 if (offset < 0 || offset > buffer.Length) {
  456.                     throw new ArgumentOutOfRangeException("offset");
  457.                 }
  458.                 if (size < 0 || size > buffer.Length - offset) {
  459.                     throw new ArgumentOutOfRangeException("size");
  460.                 }
  461.                 if (!CanRead) {
  462.                     throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
  463.                 }
  464.                
  465.                
  466.                 Socket chkStreamSocket = m_StreamSocket;
  467.                 if (chkStreamSocket == null) {
  468.                     throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  469.                 }
  470.                
  471.                 try {
  472.                     int bytesTransferred = chkStreamSocket.Receive(buffer, offset, size, 0);
  473.                     return bytesTransferred;
  474.                 }
  475.                 catch (Exception exception) {
  476.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  477.                         throw;
  478.                     }
  479.                    
  480.                     //
  481.                     // some sort of error occured on the socket call,
  482.                     // set the SocketException as InnerException and throw
  483.                     //
  484.                     throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
  485.                 }
  486.                 #if DEBUG
  487.             }
  488.             #endif
  489.         }
  490.        
  491. /*++
  492.             Write - provide core Write functionality.
  493.             Provide core write functionality. All we do is call through to the
  494.             socket Send method..
  495.             Input:
  496.                 Buffer  - Buffer to write from.
  497.                 Offset  - Offset into the buffer from where we'll start writing.
  498.                 Count  - Number of bytes to write.
  499.             Returns:
  500.                 Number of bytes written. We'll throw an exception if we
  501.                 can't write everything. It's brutal, but there's no other
  502.                 way to indicate an error.
  503.         --*/       
  504.        
  505.         /// <devdoc>
  506.         /// <para>
  507.         /// Writes data to the stream..
  508.         /// </para>
  509.         /// </devdoc>
  510.         public override void Write(byte[] buffer, int offset, int size)
  511.         {
  512.             #if DEBUG
  513.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
  514.                 #endif
  515.                 if (m_CleanedUp) {
  516.                     throw new ObjectDisposedException(this.GetType().FullName);
  517.                 }
  518.                 //
  519.                 // parameter validation
  520.                 //
  521.                 if (buffer == null) {
  522.                     throw new ArgumentNullException("buffer");
  523.                 }
  524.                 if (offset < 0 || offset > buffer.Length) {
  525.                     throw new ArgumentOutOfRangeException("offset");
  526.                 }
  527.                 if (size < 0 || size > buffer.Length - offset) {
  528.                     throw new ArgumentOutOfRangeException("size");
  529.                 }
  530.                 if (!CanWrite) {
  531.                     throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
  532.                 }
  533.                
  534.                
  535.                 Socket chkStreamSocket = m_StreamSocket;
  536.                 if (chkStreamSocket == null) {
  537.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  538.                 }
  539.                
  540.                 try {
  541.                     //
  542.                     // since the socket is in blocking mode this will always complete
  543.                     // after ALL the requested number of bytes was transferred
  544.                     //
  545.                     chkStreamSocket.Send(buffer, offset, size, SocketFlags.None);
  546.                 }
  547.                 catch (Exception exception) {
  548.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  549.                         throw;
  550.                     }
  551.                    
  552.                     //
  553.                     // some sort of error occured on the socket call,
  554.                     // set the SocketException as InnerException and throw
  555.                     //
  556.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  557.                 }
  558.                 catch {
  559.                     //
  560.                     // some sort of error occured on the socket call,
  561.                     // set the SocketException as InnerException and throw
  562.                     //
  563.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  564.                 }
  565.                 #if DEBUG
  566.             }
  567.             #endif
  568.         }
  569.        
  570.         private int m_CloseTimeout = Socket.DefaultCloseTimeout;
  571.         // 1 ms; -1 = respect linger options
  572.         public void Close(int timeout)
  573.         {
  574.             #if DEBUG
  575.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
  576.                 #endif
  577.                 if (timeout < -1) {
  578.                     throw new ArgumentOutOfRangeException("timeout");
  579.                 }
  580.                 m_CloseTimeout = timeout;
  581.                 Close();
  582.                 #if DEBUG
  583.             }
  584.             #endif
  585.         }
  586.        
  587.         private bool m_CleanedUp = false;
  588.         protected override void Dispose(bool disposing)
  589.         {
  590.             #if DEBUG
  591.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  592.                 #endif
  593.                 if (!m_CleanedUp && disposing) {
  594.                     //
  595.                     // only resource we need to free is the network stream, since this
  596.                     // is based on the client socket, closing the stream will cause us
  597.                     // to flush the data to the network, close the stream and (in the
  598.                     // NetoworkStream code) close the socket as well.
  599.                     //
  600.                     if (m_StreamSocket != null) {
  601.                         m_Readable = false;
  602.                         m_Writeable = false;
  603.                         if (m_OwnsSocket) {
  604.                             //
  605.                             // if we own the Socket (false by default), close it
  606.                             // swallowing possible exceptions (eg: the user told us
  607.                             // that we own the Socket but it closed at some point of time,
  608.                             // here we would get an ObjectDisposedException)
  609.                             //
  610.                             Socket chkStreamSocket = m_StreamSocket;
  611.                             if (chkStreamSocket != null) {
  612.                                 chkStreamSocket.InternalShutdown(SocketShutdown.Both);
  613.                                 chkStreamSocket.Close(m_CloseTimeout);
  614.                             }
  615.                         }
  616.                     }
  617.                 }
  618.                 m_CleanedUp = true;
  619.                 #if DEBUG
  620.             }
  621.             #endif
  622.             base.Dispose(disposing);
  623.         }
  624.        
  625.         ~NetworkStream()
  626.         {
  627.             #if DEBUG
  628.             GlobalLog.SetThreadSource(ThreadKinds.Finalization);
  629.             // using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) {
  630.             #endif
  631.             Dispose(false);
  632.             #if DEBUG
  633.             // }
  634.             #endif
  635.         }
  636.        
  637.         /// <devdoc>
  638.         /// <para>
  639.         /// Indicates whether the stream is still connected
  640.         /// </para>
  641.         /// </devdoc>
  642.         internal bool Connected {
  643.             get {
  644.                 Socket socket = m_StreamSocket;
  645.                 if (!m_CleanedUp && socket != null && socket.Connected) {
  646.                     return true;
  647.                 }
  648.                 else {
  649.                     return false;
  650.                 }
  651.             }
  652.         }
  653.        
  654.        
  655. /*++
  656.             BeginRead - provide async read functionality.
  657.             This method provides async read functionality. All we do is
  658.             call through to the underlying socket async read.
  659.             Input:
  660.                 buffer  - Buffer to read into.
  661.                 offset  - Offset into the buffer where we're to read.
  662.                 size  - Number of bytes to read.
  663.             Returns:
  664.                 An IASyncResult, representing the read.
  665.         --*/       
  666.        
  667.         /// <devdoc>
  668.         /// <para>
  669.         /// Begins an asychronous read from a stream.
  670.         /// </para>
  671.         /// </devdoc>
  672.         [HostProtection(ExternalThreading = true)]
  673.         public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  674.         {
  675.             #if DEBUG
  676.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  677.                 #endif
  678.                 if (m_CleanedUp) {
  679.                     throw new ObjectDisposedException(this.GetType().FullName);
  680.                 }
  681.                 //
  682.                 // parameter validation
  683.                 //
  684.                 if (buffer == null) {
  685.                     throw new ArgumentNullException("buffer");
  686.                 }
  687.                 if (offset < 0 || offset > buffer.Length) {
  688.                     throw new ArgumentOutOfRangeException("offset");
  689.                 }
  690.                 if (size < 0 || size > buffer.Length - offset) {
  691.                     throw new ArgumentOutOfRangeException("size");
  692.                 }
  693.                 if (!CanRead) {
  694.                     throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
  695.                 }
  696.                
  697.                 Socket chkStreamSocket = m_StreamSocket;
  698.                 if (chkStreamSocket == null) {
  699.                     throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  700.                 }
  701.                
  702.                 try {
  703.                     IAsyncResult asyncResult = chkStreamSocket.BeginReceive(buffer, offset, size, SocketFlags.None, callback, state);
  704.                    
  705.                     return asyncResult;
  706.                 }
  707.                 catch (Exception exception) {
  708.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  709.                         throw;
  710.                     }
  711.                    
  712.                     //
  713.                     // some sort of error occured on the socket call,
  714.                     // set the SocketException as InnerException and throw
  715.                     //
  716.                     throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
  717.                 }
  718.                 catch {
  719.                     //
  720.                     // some sort of error occured on the socket call,
  721.                     // set the SocketException as InnerException and throw
  722.                     //
  723.                     throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  724.                 }
  725.                 #if DEBUG
  726.             }
  727.             #endif
  728.         }
  729.        
  730.         internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  731.         {
  732.             if (m_CleanedUp) {
  733.                 throw new ObjectDisposedException(GetType().FullName);
  734.             }
  735.             if (!CanRead) {
  736.                 throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
  737.             }
  738.            
  739.             Socket chkStreamSocket = m_StreamSocket;
  740.             if (chkStreamSocket == null) {
  741.                 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  742.             }
  743.            
  744.             try {
  745.                 IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginReceive(buffer, offset, size, SocketFlags.None, callback, state);
  746.                
  747.                 return asyncResult;
  748.             }
  749.             catch (Exception exception) {
  750.                 if (NclUtilities.IsFatal(exception))
  751.                     throw;
  752.                
  753.                 //
  754.                 // some sort of error occured on the socket call,
  755.                 // set the SocketException as InnerException and throw
  756.                 //
  757.                 throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
  758.             }
  759.             catch {
  760.                 //
  761.                 // some sort of error occured on the socket call,
  762.                 // set the SocketException as InnerException and throw
  763.                 //
  764.                 throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  765.             }
  766.         }
  767.        
  768. /*++
  769.             EndRead - handle the end of an async read.
  770.             This method is called when an async read is completed. All we
  771.             do is call through to the core socket EndReceive functionality.
  772.             Input:
  773.                 buffer  - Buffer to read into.
  774.                 offset  - Offset into the buffer where we're to read.
  775.                 size  - Number of bytes to read.
  776.             Returns:
  777.                 The number of bytes read. May throw an exception.
  778.         --*/       
  779.        
  780.         /// <devdoc>
  781.         /// <para>
  782.         /// Handle the end of an asynchronous read.
  783.         /// </para>
  784.         /// </devdoc>
  785.         public override int EndRead(IAsyncResult asyncResult)
  786.         {
  787.             #if DEBUG
  788.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  789.                 #endif
  790.                 if (m_CleanedUp) {
  791.                     throw new ObjectDisposedException(this.GetType().FullName);
  792.                 }
  793.                
  794.                 //
  795.                 // parameter validation
  796.                 //
  797.                 if (asyncResult == null) {
  798.                     throw new ArgumentNullException("asyncResult");
  799.                 }
  800.                
  801.                 Socket chkStreamSocket = m_StreamSocket;
  802.                 if (chkStreamSocket == null) {
  803.                     throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
  804.                 }
  805.                
  806.                 try {
  807.                     int bytesTransferred = chkStreamSocket.EndReceive(asyncResult);
  808.                     return bytesTransferred;
  809.                 }
  810.                 catch (Exception exception) {
  811.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  812.                         throw;
  813.                     }
  814.                    
  815.                     //
  816.                     // some sort of error occured on the socket call,
  817.                     // set the SocketException as InnerException and throw
  818.                     //
  819.                     throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
  820.                 }
  821.                 catch {
  822.                     //
  823.                     // some sort of error occured on the socket call,
  824.                     // set the SocketException as InnerException and throw
  825.                     //
  826.                     throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  827.                 }
  828.                 #if DEBUG
  829.             }
  830.             #endif
  831.         }
  832.        
  833. /*++
  834.             BeginWrite - provide async write functionality.
  835.             This method provides async write functionality. All we do is
  836.             call through to the underlying socket async send.
  837.             Input:
  838.                 buffer  - Buffer to write into.
  839.                 offset  - Offset into the buffer where we're to write.
  840.                 size  - Number of bytes to written.
  841.             Returns:
  842.                 An IASyncResult, representing the write.
  843.         --*/       
  844.        
  845.         /// <devdoc>
  846.         /// <para>
  847.         /// Begins an asynchronous write to a stream.
  848.         /// </para>
  849.         /// </devdoc>
  850.         [HostProtection(ExternalThreading = true)]
  851.         public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  852.         {
  853.             #if DEBUG
  854.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  855.                 #endif
  856.                 if (m_CleanedUp) {
  857.                     throw new ObjectDisposedException(this.GetType().FullName);
  858.                 }
  859.                 //
  860.                 // parameter validation
  861.                 //
  862.                 if (buffer == null) {
  863.                     throw new ArgumentNullException("buffer");
  864.                 }
  865.                 if (offset < 0 || offset > buffer.Length) {
  866.                     throw new ArgumentOutOfRangeException("offset");
  867.                 }
  868.                 if (size < 0 || size > buffer.Length - offset) {
  869.                     throw new ArgumentOutOfRangeException("size");
  870.                 }
  871.                 if (!CanWrite) {
  872.                     throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
  873.                 }
  874.                
  875.                 Socket chkStreamSocket = m_StreamSocket;
  876.                 if (chkStreamSocket == null) {
  877.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  878.                 }
  879.                
  880.                 try {
  881.                     //
  882.                     // call BeginSend on the Socket.
  883.                     //
  884.                     IAsyncResult asyncResult = chkStreamSocket.BeginSend(buffer, offset, size, SocketFlags.None, callback, state);
  885.                    
  886.                     return asyncResult;
  887.                 }
  888.                 catch (Exception exception) {
  889.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  890.                         throw;
  891.                     }
  892.                    
  893.                     //
  894.                     // some sort of error occured on the socket call,
  895.                     // set the SocketException as InnerException and throw
  896.                     //
  897.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  898.                 }
  899.                 catch {
  900.                     //
  901.                     // some sort of error occured on the socket call,
  902.                     // set the SocketException as InnerException and throw
  903.                     //
  904.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  905.                 }
  906.                 #if DEBUG
  907.             }
  908.             #endif
  909.         }
  910.        
  911.        
  912.        
  913.         internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
  914.         {
  915.             #if DEBUG
  916.             using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
  917.                 #endif
  918.                 if (m_CleanedUp) {
  919.                     throw new ObjectDisposedException(this.GetType().FullName);
  920.                 }
  921.                
  922.                 if (!CanWrite) {
  923.                     throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
  924.                 }
  925.                
  926.                 Socket chkStreamSocket = m_StreamSocket;
  927.                 if (chkStreamSocket == null) {
  928.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  929.                 }
  930.                
  931.                 try {
  932.                     //
  933.                     // call BeginSend on the Socket.
  934.                     //
  935.                     IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginSend(buffer, offset, size, SocketFlags.None, callback, state);
  936.                    
  937.                     return asyncResult;
  938.                 }
  939.                 catch (Exception exception) {
  940.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  941.                         throw;
  942.                     }
  943.                    
  944.                     //
  945.                     // some sort of error occured on the socket call,
  946.                     // set the SocketException as InnerException and throw
  947.                     //
  948.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  949.                 }
  950.                 catch {
  951.                     //
  952.                     // some sort of error occured on the socket call,
  953.                     // set the SocketException as InnerException and throw
  954.                     //
  955.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  956.                 }
  957.                 #if DEBUG
  958.             }
  959.             #endif
  960.         }
  961.        
  962.        
  963.        
  964.         /// <devdoc>
  965.         /// <para>
  966.         /// Handle the end of an asynchronous write.
  967.         /// This method is called when an async write is completed. All we
  968.         /// do is call through to the core socket EndSend functionality.
  969.         /// Returns: The number of bytes read. May throw an exception.
  970.         /// </para>
  971.         /// </devdoc>
  972.         public override void EndWrite(IAsyncResult asyncResult)
  973.         {
  974.             #if DEBUG
  975.             using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
  976.                 #endif
  977.                 if (m_CleanedUp) {
  978.                     throw new ObjectDisposedException(this.GetType().FullName);
  979.                 }
  980.                
  981.                 //
  982.                 // parameter validation
  983.                 //
  984.                 if (asyncResult == null) {
  985.                     throw new ArgumentNullException("asyncResult");
  986.                 }
  987.                
  988.                 Socket chkStreamSocket = m_StreamSocket;
  989.                 if (chkStreamSocket == null) {
  990.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  991.                 }
  992.                
  993.                 try {
  994.                     chkStreamSocket.EndSend(asyncResult);
  995.                 }
  996.                 catch (Exception exception) {
  997.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  998.                         throw;
  999.                     }
  1000.                    
  1001.                     //
  1002.                     // some sort of error occured on the socket call,
  1003.                     // set the SocketException as InnerException and throw
  1004.                     //
  1005.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  1006.                 }
  1007.                 catch {
  1008.                     //
  1009.                     // some sort of error occured on the socket call,
  1010.                     // set the SocketException as InnerException and throw
  1011.                     //
  1012.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1013.                 }
  1014.                 #if DEBUG
  1015.             }
  1016.             #endif
  1017.         }
  1018.        
  1019.        
  1020.         /// <devdoc>
  1021.         /// <para>
  1022.         /// Performs a sync Write of an array of buffers.
  1023.         /// </para>
  1024.         /// </devdoc>
  1025.         internal virtual void MultipleWrite(BufferOffsetSize[] buffers)
  1026.         {
  1027.             GlobalLog.ThreadContract(ThreadKinds.Sync, "NetworkStream#" + ValidationHelper.HashString(this) + "::MultipleWrite");
  1028.            
  1029.             //
  1030.             // parameter validation
  1031.             //
  1032.             if (buffers == null) {
  1033.                 throw new ArgumentNullException("buffers");
  1034.             }
  1035.            
  1036.             Socket chkStreamSocket = m_StreamSocket;
  1037.             if (chkStreamSocket == null) {
  1038.                 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  1039.             }
  1040.            
  1041.             try {
  1042.                 buffers = ConcatenateBuffersOnWin9x(buffers);
  1043.                
  1044.                 chkStreamSocket.MultipleSend(buffers, SocketFlags.None);
  1045.                
  1046.             }
  1047.             catch (Exception exception) {
  1048.                 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  1049.                     throw;
  1050.                 }
  1051.                
  1052.                 //
  1053.                 // some sort of error occured on the socket call,
  1054.                 // set the SocketException as InnerException and throw
  1055.                 //
  1056.                 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  1057.             }
  1058.             catch {
  1059.                 //
  1060.                 // some sort of error occured on the socket call,
  1061.                 // set the SocketException as InnerException and throw
  1062.                 //
  1063.                 throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1064.             }
  1065.         }
  1066.        
  1067.        
  1068.         /// <devdoc>
  1069.         /// <para>
  1070.         /// Starts off an async Write of an array of buffers.
  1071.         /// </para>
  1072.         /// </devdoc>
  1073.         internal virtual IAsyncResult BeginMultipleWrite(BufferOffsetSize[] buffers, AsyncCallback callback, object state)
  1074.         {
  1075.             #if DEBUG
  1076.             GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite");
  1077.             using (GlobalLog.SetThreadKind(ThreadKinds.Async)) {
  1078.                 #endif
  1079.                
  1080.                 //
  1081.                 // parameter validation
  1082.                 //
  1083.                 if (buffers == null) {
  1084.                     throw new ArgumentNullException("buffers");
  1085.                 }
  1086.                
  1087.                 Socket chkStreamSocket = m_StreamSocket;
  1088.                 if (chkStreamSocket == null) {
  1089.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  1090.                 }
  1091.                
  1092.                 try {
  1093.                     buffers = ConcatenateBuffersOnWin9x(buffers);
  1094.                    
  1095.                     //
  1096.                     // call BeginMultipleSend on the Socket.
  1097.                     //
  1098.                     IAsyncResult asyncResult = chkStreamSocket.BeginMultipleSend(buffers, SocketFlags.None, callback, state);
  1099.                    
  1100.                     return asyncResult;
  1101.                 }
  1102.                 catch (Exception exception) {
  1103.                    
  1104.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  1105.                         throw;
  1106.                     }
  1107.                    
  1108.                     //
  1109.                     // some sort of error occured on the socket call,
  1110.                     // set the SocketException as InnerException and throw
  1111.                     //
  1112.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  1113.                 }
  1114.                 catch {
  1115.                    
  1116.                     //
  1117.                     // some sort of error occured on the socket call,
  1118.                     // set the SocketException as InnerException and throw
  1119.                     //
  1120.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1121.                 }
  1122.                 #if DEBUG
  1123.             }
  1124.             #endif
  1125.         }
  1126.        
  1127.        
  1128.         internal virtual IAsyncResult UnsafeBeginMultipleWrite(BufferOffsetSize[] buffers, AsyncCallback callback, object state)
  1129.         {
  1130.             #if DEBUG
  1131.             GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite");
  1132.             using (GlobalLog.SetThreadKind(ThreadKinds.Async)) {
  1133.                 #endif
  1134.                
  1135.                 //
  1136.                 // parameter validation
  1137.                 //
  1138.                 if (buffers == null) {
  1139.                     throw new ArgumentNullException("buffers");
  1140.                 }
  1141.                
  1142.                 Socket chkStreamSocket = m_StreamSocket;
  1143.                 if (chkStreamSocket == null) {
  1144.                     throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  1145.                 }
  1146.                
  1147.                 try {
  1148.                     buffers = ConcatenateBuffersOnWin9x(buffers);
  1149.                    
  1150.                     //
  1151.                     // call BeginMultipleSend on the Socket.
  1152.                     //
  1153.                     IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginMultipleSend(buffers, SocketFlags.None, callback, state);
  1154.                    
  1155.                     return asyncResult;
  1156.                 }
  1157.                 catch (Exception exception) {
  1158.                    
  1159.                     if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  1160.                         throw;
  1161.                     }
  1162.                    
  1163.                     //
  1164.                     // some sort of error occured on the socket call,
  1165.                     // set the SocketException as InnerException and throw
  1166.                     //
  1167.                     throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  1168.                 }
  1169.                 catch {
  1170.                    
  1171.                     //
  1172.                     // some sort of error occured on the socket call,
  1173.                     // set the SocketException as InnerException and throw
  1174.                     //
  1175.                     throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1176.                 }
  1177.                 #if DEBUG
  1178.             }
  1179.             #endif
  1180.         }
  1181.        
  1182.        
  1183.         internal virtual void EndMultipleWrite(IAsyncResult asyncResult)
  1184.         {
  1185.             GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::EndMultipleWrite");
  1186.            
  1187.             //
  1188.             // parameter validation
  1189.             //
  1190.             if (asyncResult == null) {
  1191.                 throw new ArgumentNullException("asyncResult");
  1192.             }
  1193.            
  1194.             Socket chkStreamSocket = m_StreamSocket;
  1195.             if (chkStreamSocket == null) {
  1196.                 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
  1197.             }
  1198.            
  1199.             try {
  1200.                 chkStreamSocket.EndMultipleSend(asyncResult);
  1201.             }
  1202.             catch (Exception exception) {
  1203.                 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  1204.                     throw;
  1205.                 }
  1206.                
  1207.                 //
  1208.                 // some sort of error occured on the socket call,
  1209.                 // set the SocketException as InnerException and throw
  1210.                 //
  1211.                 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
  1212.             }
  1213.             catch {
  1214.                 //
  1215.                 // some sort of error occured on the socket call,
  1216.                 // set the SocketException as InnerException and throw
  1217.                 //
  1218.                 throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException)));
  1219.             }
  1220.         }
  1221.        
  1222.         /// <devdoc>
  1223.         /// <para>
  1224.         /// Due to Winsock restrictions
  1225.         /// If on Win9x platforms and the number of buffers are more than 16, performs
  1226.         /// concatenation of the buffers, so that we have 16 buffers.
  1227.         /// </para>
  1228.         /// </devdoc>
  1229.         private BufferOffsetSize[] ConcatenateBuffersOnWin9x(BufferOffsetSize[] buffers)
  1230.         {
  1231.             return buffers;
  1232.         }
  1233.        
  1234.         /// <devdoc>
  1235.         /// <para>
  1236.         /// Flushes data from the stream. This is meaningless for us, so it does nothing.
  1237.         /// </para>
  1238.         /// </devdoc>
  1239.         public override void Flush()
  1240.         {
  1241.         }
  1242.        
  1243.         /// <devdoc>
  1244.         /// <para>
  1245.         /// Sets the length of the stream. Always throws <see cref='NotSupportedException'/>
  1246.         /// </para>
  1247.         /// </devdoc>
  1248.         public override void SetLength(long value)
  1249.         {
  1250.             throw new NotSupportedException(SR.GetString(SR.net_noseek));
  1251.         }
  1252.        
  1253.         int m_CurrentReadTimeout = -1;
  1254.         int m_CurrentWriteTimeout = -1;
  1255.         internal void SetSocketTimeoutOption(SocketShutdown mode, int timeout, bool silent)
  1256.         {
  1257.             GlobalLog.Print("NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption() mode:" + mode + " silent:" + silent + " timeout:" + timeout + " m_CurrentReadTimeout:" + m_CurrentReadTimeout + " m_CurrentWriteTimeout:" + m_CurrentWriteTimeout);
  1258.             GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption");
  1259.            
  1260.             if (timeout < 0) {
  1261.                 timeout = 0;
  1262.                 // -1 becomes 0 for the winsock stack
  1263.             }
  1264.            
  1265.             Socket chkStreamSocket = m_StreamSocket;
  1266.             if (chkStreamSocket == null) {
  1267.                 return;
  1268.             }
  1269.             if (mode == SocketShutdown.Send || mode == SocketShutdown.Both) {
  1270.                 if (timeout != m_CurrentWriteTimeout) {
  1271.                     chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout, silent);
  1272.                     m_CurrentWriteTimeout = timeout;
  1273.                 }
  1274.             }
  1275.             if (mode == SocketShutdown.Receive || mode == SocketShutdown.Both) {
  1276.                 if (timeout != m_CurrentReadTimeout) {
  1277.                     chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout, silent);
  1278.                     m_CurrentReadTimeout = timeout;
  1279.                 }
  1280.             }
  1281.         }
  1282.        
  1283.     }
  1284. }

Developer Fusion