Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Net / System / Net / Sockets / NetworkStream.cs / 1 / NetworkStream.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net.Sockets { using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Security.Permissions; ////// public class NetworkStream : Stream { ////// Provides the underlying stream of data for network access. /// ////// private Socket m_StreamSocket; ////// Used by the class to hold the underlying socket the stream uses. /// ////// private bool m_Readable; ////// Used by the class to indicate that the stream is m_Readable. /// ////// private bool m_Writeable; private bool m_OwnsSocket; ////// Used by the class to indicate that the stream is writable. /// ////// internal NetworkStream() { m_OwnsSocket = true; } // Can be constructed directly out of a socket ///Creates a new instance of the ///without initalization. /// public NetworkStream(Socket socket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, FileAccess.ReadWrite); #if DEBUG } #endif } //UEUE (see FileStream) // ownsHandle: true if the file handle will be owned by this NetworkStream instance; otherwise, false. public NetworkStream(Socket socket, bool ownsSocket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, FileAccess.ReadWrite); m_OwnsSocket = ownsSocket; #if DEBUG } #endif } internal NetworkStream(NetworkStream networkStream, bool ownsSocket) { Socket socket = networkStream.Socket; if (socket == null) { throw new ArgumentNullException("networkStream"); } InitNetworkStream(socket, FileAccess.ReadWrite); m_OwnsSocket = ownsSocket; } // Create with a socket and access mode ///Creates a new instance of the ///class for the specified . /// public NetworkStream(Socket socket, FileAccess access) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, access); #if DEBUG } #endif } public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, access); m_OwnsSocket = ownsSocket; #if DEBUG } #endif } // // Socket - provides access to socket for stream closing // protected Socket Socket { get { return m_StreamSocket; } } internal Socket InternalSocket { get { Socket chkSocket = m_StreamSocket; if (m_CleanedUp || chkSocket == null) { throw new ObjectDisposedException(this.GetType().FullName); } return chkSocket; } } internal void ConvertToNotSocketOwner() { m_OwnsSocket = false; // Suppress for finialization still allow proceed the requests GC.SuppressFinalize(this); } ///Creates a new instance of the ///class for the specified with the specified access rights. /// protected bool Readable { get { return m_Readable; } set { m_Readable = value; } } ////// Used by the class to indicate that the stream is m_Readable. /// ////// protected bool Writeable { get { return m_Writeable; } set { m_Writeable = value; } } ////// Used by the class to indicate that the stream is writable. /// ////// public override bool CanRead { get { return m_Readable; } } ////// Indicates that data can be read from the stream. /// We return the readability of this stream. This is a read only property. /// ////// public override bool CanSeek { get { return false; } } ////// Indicates that the stream can seek a specific location /// in the stream. This property always returns ////// . /// /// public override bool CanWrite { get { return m_Writeable; } } ////// Indicates that data can be written to the stream. /// ////// public override bool CanTimeout { get { return true; // should we check for Connected state? } } ///Indicates whether we can timeout ////// public override int ReadTimeout { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout); if (timeout == 0) { return -1; } return timeout; #if DEBUG } #endif } set { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (value<=0 && value!=System.Threading.Timeout.Infinite) { throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); } SetSocketTimeoutOption(SocketShutdown.Receive, value, false); #if DEBUG } #endif } } ///Set/Get ReadTimeout, note of a strange behavior, 0 timeout == infinite for sockets, /// so we map this to -1, and if you set 0, we cannot support it ////// public override int WriteTimeout { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout); if (timeout == 0) { return -1; } return timeout; #if DEBUG } #endif } set { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (value <= 0 && value != System.Threading.Timeout.Infinite) { throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); } SetSocketTimeoutOption(SocketShutdown.Send, value, false); #if DEBUG } #endif } } ///Set/Get WriteTimeout, note of a strange behavior, 0 timeout == infinite for sockets, /// so we map this to -1, and if you set 0, we cannot support it ////// public virtual bool DataAvailable { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } // Ask the socket how many bytes are available. If it's // not zero, return true. return chkStreamSocket.Available != 0; #if DEBUG } #endif } } ////// Indicates data is available on the stream to be read. /// This property checks to see if at least one byte of data is currently available /// ////// public override long Length { get { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } } ////// The length of data available on the stream. Always throws ///. /// /// public override long Position { get { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } set { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } } ////// Gets or sets the position in the stream. Always throws ///. /// /// public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } /*++ InitNetworkStream - initialize a network stream. This is the common NetworkStream constructor, called whenever a network stream is created. We validate the socket, set a few options, and call our parent's initializer. Input: S - Socket to be used. Access - Access type desired. Returns: Nothing, but may throw an exception. --*/ internal void InitNetworkStream(Socket socket, FileAccess Access) { // // parameter validation // if (!socket.Blocking) { throw new IOException(SR.GetString(SR.net_sockets_blocking)); } if (!socket.Connected) { throw new IOException(SR.GetString(SR.net_notconnected)); } if (socket.SocketType != SocketType.Stream) { throw new IOException(SR.GetString(SR.net_notstream)); } m_StreamSocket = socket; switch (Access) { case FileAccess.Read: m_Readable = true; break; case FileAccess.Write: m_Writeable = true; break; case FileAccess.ReadWrite: default: // assume FileAccess.ReadWrite m_Readable = true; m_Writeable = true; break; } } internal bool PollRead() { if (m_CleanedUp) { return false; } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { return false; } return chkStreamSocket.Poll(0, SelectMode.SelectRead); } internal bool Poll(int microSeconds, SelectMode mode) { if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } return chkStreamSocket.Poll(microSeconds, mode); } /*++ Read - provide core Read functionality. Provide core read functionality. All we do is call through to the socket Receive functionality. Input: Buffer - Buffer to read into. Offset - Offset into the buffer where we're to read. Count - Number of bytes to read. Returns: Number of bytes we read, or 0 if the socket is closed. --*/ ////// Seeks a specific position in the stream. This method is not supported by the /// ///class. /// /// //UEUE public override int Read([In, Out] byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { int bytesTransferred = chkStreamSocket.Receive(buffer, offset, size, 0); return bytesTransferred; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } #if DEBUG } #endif } /*++ Write - provide core Write functionality. Provide core write functionality. All we do is call through to the socket Send method.. Input: Buffer - Buffer to write from. Offset - Offset into the buffer from where we'll start writing. Count - Number of bytes to write. Returns: Number of bytes written. We'll throw an exception if we can't write everything. It's brutal, but there's no other way to indicate an error. --*/ ////// Reads data from the stream. /// ////// public override void Write(byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // since the socket is in blocking mode this will always complete // after ALL the requested number of bytes was transferred // chkStreamSocket.Send(buffer, offset, size, SocketFlags.None); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } private int m_CloseTimeout = Socket.DefaultCloseTimeout; // 1 ms; -1 = respect linger options public void Close(int timeout) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (timeout < -1) { throw new ArgumentOutOfRangeException("timeout"); } m_CloseTimeout = timeout; Close(); #if DEBUG } #endif } private bool m_CleanedUp = false; protected override void Dispose(bool disposing) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (!m_CleanedUp && disposing) { // // only resource we need to free is the network stream, since this // is based on the client socket, closing the stream will cause us // to flush the data to the network, close the stream and (in the // NetoworkStream code) close the socket as well. // if (m_StreamSocket!=null) { m_Readable = false; m_Writeable = false; if (m_OwnsSocket) { // // if we own the Socket (false by default), close it // ----ing possible exceptions (eg: the user told us // that we own the Socket but it closed at some point of time, // here we would get an ObjectDisposedException) // Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket!=null) { chkStreamSocket.InternalShutdown(SocketShutdown.Both); chkStreamSocket.Close(m_CloseTimeout); } } } } m_CleanedUp = true; #if DEBUG } #endif base.Dispose(disposing); } ~NetworkStream() { #if DEBUG GlobalLog.SetThreadSource(ThreadKinds.Finalization); // using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) { #endif Dispose(false); #if DEBUG // } #endif } ////// Writes data to the stream.. /// ////// internal bool Connected { get { Socket socket = m_StreamSocket; if (!m_CleanedUp && socket !=null && socket.Connected) { return true; } else { return false; } } } /*++ BeginRead - provide async read functionality. This method provides async read functionality. All we do is call through to the underlying socket async read. Input: buffer - Buffer to read into. offset - Offset into the buffer where we're to read. size - Number of bytes to read. Returns: An IASyncResult, representing the read. --*/ ////// Indicates whether the stream is still connected /// ////// [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { IAsyncResult asyncResult = chkStreamSocket.BeginReceive( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { if (m_CleanedUp) { throw new ObjectDisposedException(GetType().FullName); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginReceive( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } /*++ EndRead - handle the end of an async read. This method is called when an async read is completed. All we do is call through to the core socket EndReceive functionality. Input: buffer - Buffer to read into. offset - Offset into the buffer where we're to read. size - Number of bytes to read. Returns: The number of bytes read. May throw an exception. --*/ ////// Begins an asychronous read from a stream. /// ////// public override int EndRead(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (asyncResult==null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { int bytesTransferred = chkStreamSocket.EndReceive(asyncResult); return bytesTransferred; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } /*++ BeginWrite - provide async write functionality. This method provides async write functionality. All we do is call through to the underlying socket async send. Input: buffer - Buffer to write into. offset - Offset into the buffer where we're to write. size - Number of bytes to written. Returns: An IASyncResult, representing the write. --*/ ////// Handle the end of an asynchronous read. /// ////// [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // call BeginSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.BeginSend( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // call BeginSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginSend( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } ////// Begins an asynchronous write to a stream. /// ////// public override void EndWrite(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (asyncResult==null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { chkStreamSocket.EndSend(asyncResult); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } ////// Handle the end of an asynchronous write. /// This method is called when an async write is completed. All we /// do is call through to the core socket EndSend functionality. /// Returns: The number of bytes read. May throw an exception. /// ////// internal virtual void MultipleWrite(BufferOffsetSize[] buffers) { GlobalLog.ThreadContract(ThreadKinds.[....], "NetworkStream#" + ValidationHelper.HashString(this) + "::MultipleWrite"); // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); chkStreamSocket.MultipleSend( buffers, SocketFlags.None); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } ////// Performs a [....] Write of an array of buffers. /// ////// internal virtual IAsyncResult BeginMultipleWrite( BufferOffsetSize[] buffers, AsyncCallback callback, Object state) { #if DEBUG GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite"); using (GlobalLog.SetThreadKind(ThreadKinds.Async)) { #endif // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); // // call BeginMultipleSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.BeginMultipleSend( buffers, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginMultipleWrite( BufferOffsetSize[] buffers, AsyncCallback callback, Object state) { #if DEBUG GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite"); using (GlobalLog.SetThreadKind(ThreadKinds.Async)) { #endif // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); // // call BeginMultipleSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginMultipleSend( buffers, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual void EndMultipleWrite(IAsyncResult asyncResult) { GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::EndMultipleWrite"); // // parameter validation // if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { chkStreamSocket.EndMultipleSend(asyncResult); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } ////// Starts off an async Write of an array of buffers. /// ////// private BufferOffsetSize[] ConcatenateBuffersOnWin9x(BufferOffsetSize[] buffers) { #if !FEATURE_PAL if (ComNetOS.IsWin9x && buffers.Length > 16) { // We met the limitation of winsock on Win9x // Combine buffers after the 15th into one so overall number does not exceed 16 BufferOffsetSize[] newBuffers = new BufferOffsetSize[16]; int i; for (i = 0; i < 16; ++i) { newBuffers[i] = buffers[i]; } int size = 0; for (i = 15; i < buffers.Length; ++i) { size += buffers[i].Size; } if (size > 0) { newBuffers[15] = new BufferOffsetSize(new byte[size], 0, size, false); for (size = 0, i = 15; i < buffers.Length; size+=buffers[i].Size, ++i) { System.Buffer.BlockCopy(buffers[i].Buffer, buffers[i].Offset, newBuffers[15].Buffer, size, buffers[i].Size); } } buffers = newBuffers; } #endif // !FEATURE_PAL return buffers; } ////// Due to Winsock restrictions /// If on Win9x platforms and the number of buffers are more than 16, performs /// concatenation of the buffers, so that we have 16 buffers. /// ////// public override void Flush() { } ////// Flushes data from the stream. This is meaningless for us, so it does nothing. /// ////// public override void SetLength(long value) { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } int m_CurrentReadTimeout = -1; int m_CurrentWriteTimeout = -1; internal void SetSocketTimeoutOption(SocketShutdown mode, int timeout, bool silent) { GlobalLog.Print("NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption() mode:" + mode + " silent:" + silent + " timeout:" + timeout + " m_CurrentReadTimeout:" + m_CurrentReadTimeout + " m_CurrentWriteTimeout:" + m_CurrentWriteTimeout); GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption"); if (timeout < 0) { timeout = 0; // -1 becomes 0 for the winsock stack } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket==null) { return; } if (mode==SocketShutdown.Send || mode==SocketShutdown.Both) { if (timeout!=m_CurrentWriteTimeout) { chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout, silent); m_CurrentWriteTimeout = timeout; } } if (mode==SocketShutdown.Receive || mode==SocketShutdown.Both) { if (timeout!=m_CurrentReadTimeout) { chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout, silent); m_CurrentReadTimeout = timeout; } } } #if TRAVE [System.Diagnostics.Conditional("TRAVE")] internal void Debug() { if (m_StreamSocket != null) { GlobalLog.Print("m_StreamSocket:"); m_StreamSocket.Debug(); } } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ ///// Sets the length of the stream. Always throws ////// // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net.Sockets { using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Security.Permissions; ////// public class NetworkStream : Stream { ////// Provides the underlying stream of data for network access. /// ////// private Socket m_StreamSocket; ////// Used by the class to hold the underlying socket the stream uses. /// ////// private bool m_Readable; ////// Used by the class to indicate that the stream is m_Readable. /// ////// private bool m_Writeable; private bool m_OwnsSocket; ////// Used by the class to indicate that the stream is writable. /// ////// internal NetworkStream() { m_OwnsSocket = true; } // Can be constructed directly out of a socket ///Creates a new instance of the ///without initalization. /// public NetworkStream(Socket socket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, FileAccess.ReadWrite); #if DEBUG } #endif } //UEUE (see FileStream) // ownsHandle: true if the file handle will be owned by this NetworkStream instance; otherwise, false. public NetworkStream(Socket socket, bool ownsSocket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, FileAccess.ReadWrite); m_OwnsSocket = ownsSocket; #if DEBUG } #endif } internal NetworkStream(NetworkStream networkStream, bool ownsSocket) { Socket socket = networkStream.Socket; if (socket == null) { throw new ArgumentNullException("networkStream"); } InitNetworkStream(socket, FileAccess.ReadWrite); m_OwnsSocket = ownsSocket; } // Create with a socket and access mode ///Creates a new instance of the ///class for the specified . /// public NetworkStream(Socket socket, FileAccess access) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, access); #if DEBUG } #endif } public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException("socket"); } InitNetworkStream(socket, access); m_OwnsSocket = ownsSocket; #if DEBUG } #endif } // // Socket - provides access to socket for stream closing // protected Socket Socket { get { return m_StreamSocket; } } internal Socket InternalSocket { get { Socket chkSocket = m_StreamSocket; if (m_CleanedUp || chkSocket == null) { throw new ObjectDisposedException(this.GetType().FullName); } return chkSocket; } } internal void ConvertToNotSocketOwner() { m_OwnsSocket = false; // Suppress for finialization still allow proceed the requests GC.SuppressFinalize(this); } ///Creates a new instance of the ///class for the specified with the specified access rights. /// protected bool Readable { get { return m_Readable; } set { m_Readable = value; } } ////// Used by the class to indicate that the stream is m_Readable. /// ////// protected bool Writeable { get { return m_Writeable; } set { m_Writeable = value; } } ////// Used by the class to indicate that the stream is writable. /// ////// public override bool CanRead { get { return m_Readable; } } ////// Indicates that data can be read from the stream. /// We return the readability of this stream. This is a read only property. /// ////// public override bool CanSeek { get { return false; } } ////// Indicates that the stream can seek a specific location /// in the stream. This property always returns ////// . /// /// public override bool CanWrite { get { return m_Writeable; } } ////// Indicates that data can be written to the stream. /// ////// public override bool CanTimeout { get { return true; // should we check for Connected state? } } ///Indicates whether we can timeout ////// public override int ReadTimeout { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout); if (timeout == 0) { return -1; } return timeout; #if DEBUG } #endif } set { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (value<=0 && value!=System.Threading.Timeout.Infinite) { throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); } SetSocketTimeoutOption(SocketShutdown.Receive, value, false); #if DEBUG } #endif } } ///Set/Get ReadTimeout, note of a strange behavior, 0 timeout == infinite for sockets, /// so we map this to -1, and if you set 0, we cannot support it ////// public override int WriteTimeout { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout); if (timeout == 0) { return -1; } return timeout; #if DEBUG } #endif } set { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (value <= 0 && value != System.Threading.Timeout.Infinite) { throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); } SetSocketTimeoutOption(SocketShutdown.Send, value, false); #if DEBUG } #endif } } ///Set/Get WriteTimeout, note of a strange behavior, 0 timeout == infinite for sockets, /// so we map this to -1, and if you set 0, we cannot support it ////// public virtual bool DataAvailable { get { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } // Ask the socket how many bytes are available. If it's // not zero, return true. return chkStreamSocket.Available != 0; #if DEBUG } #endif } } ////// Indicates data is available on the stream to be read. /// This property checks to see if at least one byte of data is currently available /// ////// public override long Length { get { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } } ////// The length of data available on the stream. Always throws ///. /// /// public override long Position { get { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } set { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } } ////// Gets or sets the position in the stream. Always throws ///. /// /// public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } /*++ InitNetworkStream - initialize a network stream. This is the common NetworkStream constructor, called whenever a network stream is created. We validate the socket, set a few options, and call our parent's initializer. Input: S - Socket to be used. Access - Access type desired. Returns: Nothing, but may throw an exception. --*/ internal void InitNetworkStream(Socket socket, FileAccess Access) { // // parameter validation // if (!socket.Blocking) { throw new IOException(SR.GetString(SR.net_sockets_blocking)); } if (!socket.Connected) { throw new IOException(SR.GetString(SR.net_notconnected)); } if (socket.SocketType != SocketType.Stream) { throw new IOException(SR.GetString(SR.net_notstream)); } m_StreamSocket = socket; switch (Access) { case FileAccess.Read: m_Readable = true; break; case FileAccess.Write: m_Writeable = true; break; case FileAccess.ReadWrite: default: // assume FileAccess.ReadWrite m_Readable = true; m_Writeable = true; break; } } internal bool PollRead() { if (m_CleanedUp) { return false; } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { return false; } return chkStreamSocket.Poll(0, SelectMode.SelectRead); } internal bool Poll(int microSeconds, SelectMode mode) { if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } return chkStreamSocket.Poll(microSeconds, mode); } /*++ Read - provide core Read functionality. Provide core read functionality. All we do is call through to the socket Receive functionality. Input: Buffer - Buffer to read into. Offset - Offset into the buffer where we're to read. Count - Number of bytes to read. Returns: Number of bytes we read, or 0 if the socket is closed. --*/ ////// Seeks a specific position in the stream. This method is not supported by the /// ///class. /// /// //UEUE public override int Read([In, Out] byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { int bytesTransferred = chkStreamSocket.Receive(buffer, offset, size, 0); return bytesTransferred; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } #if DEBUG } #endif } /*++ Write - provide core Write functionality. Provide core write functionality. All we do is call through to the socket Send method.. Input: Buffer - Buffer to write from. Offset - Offset into the buffer from where we'll start writing. Count - Number of bytes to write. Returns: Number of bytes written. We'll throw an exception if we can't write everything. It's brutal, but there's no other way to indicate an error. --*/ ////// Reads data from the stream. /// ////// public override void Write(byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // since the socket is in blocking mode this will always complete // after ALL the requested number of bytes was transferred // chkStreamSocket.Send(buffer, offset, size, SocketFlags.None); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } private int m_CloseTimeout = Socket.DefaultCloseTimeout; // 1 ms; -1 = respect linger options public void Close(int timeout) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { #endif if (timeout < -1) { throw new ArgumentOutOfRangeException("timeout"); } m_CloseTimeout = timeout; Close(); #if DEBUG } #endif } private bool m_CleanedUp = false; protected override void Dispose(bool disposing) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (!m_CleanedUp && disposing) { // // only resource we need to free is the network stream, since this // is based on the client socket, closing the stream will cause us // to flush the data to the network, close the stream and (in the // NetoworkStream code) close the socket as well. // if (m_StreamSocket!=null) { m_Readable = false; m_Writeable = false; if (m_OwnsSocket) { // // if we own the Socket (false by default), close it // ----ing possible exceptions (eg: the user told us // that we own the Socket but it closed at some point of time, // here we would get an ObjectDisposedException) // Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket!=null) { chkStreamSocket.InternalShutdown(SocketShutdown.Both); chkStreamSocket.Close(m_CloseTimeout); } } } } m_CleanedUp = true; #if DEBUG } #endif base.Dispose(disposing); } ~NetworkStream() { #if DEBUG GlobalLog.SetThreadSource(ThreadKinds.Finalization); // using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) { #endif Dispose(false); #if DEBUG // } #endif } ////// Writes data to the stream.. /// ////// internal bool Connected { get { Socket socket = m_StreamSocket; if (!m_CleanedUp && socket !=null && socket.Connected) { return true; } else { return false; } } } /*++ BeginRead - provide async read functionality. This method provides async read functionality. All we do is call through to the underlying socket async read. Input: buffer - Buffer to read into. offset - Offset into the buffer where we're to read. size - Number of bytes to read. Returns: An IASyncResult, representing the read. --*/ ////// Indicates whether the stream is still connected /// ////// [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { IAsyncResult asyncResult = chkStreamSocket.BeginReceive( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { if (m_CleanedUp) { throw new ObjectDisposedException(GetType().FullName); } if (!CanRead) { throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream)); } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginReceive( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } /*++ EndRead - handle the end of an async read. This method is called when an async read is completed. All we do is call through to the core socket EndReceive functionality. Input: buffer - Buffer to read into. offset - Offset into the buffer where we're to read. size - Number of bytes to read. Returns: The number of bytes read. May throw an exception. --*/ ////// Begins an asychronous read from a stream. /// ////// public override int EndRead(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (asyncResult==null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed))); } try { int bytesTransferred = chkStreamSocket.EndReceive(asyncResult); return bytesTransferred; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_readfailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } /*++ BeginWrite - provide async write functionality. This method provides async write functionality. All we do is call through to the underlying socket async send. Input: buffer - Buffer to write into. offset - Offset into the buffer where we're to write. size - Number of bytes to written. Returns: An IASyncResult, representing the write. --*/ ////// Handle the end of an asynchronous read. /// ////// [HostProtection(ExternalThreading=true)] public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // call BeginSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.BeginSend( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // call BeginSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginSend( buffer, offset, size, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } ////// Begins an asynchronous write to a stream. /// ////// public override void EndWrite(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (asyncResult==null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { chkStreamSocket.EndSend(asyncResult); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } ////// Handle the end of an asynchronous write. /// This method is called when an async write is completed. All we /// do is call through to the core socket EndSend functionality. /// Returns: The number of bytes read. May throw an exception. /// ////// internal virtual void MultipleWrite(BufferOffsetSize[] buffers) { GlobalLog.ThreadContract(ThreadKinds.[....], "NetworkStream#" + ValidationHelper.HashString(this) + "::MultipleWrite"); // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); chkStreamSocket.MultipleSend( buffers, SocketFlags.None); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } ////// Performs a [....] Write of an array of buffers. /// ////// internal virtual IAsyncResult BeginMultipleWrite( BufferOffsetSize[] buffers, AsyncCallback callback, Object state) { #if DEBUG GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite"); using (GlobalLog.SetThreadKind(ThreadKinds.Async)) { #endif // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); // // call BeginMultipleSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.BeginMultipleSend( buffers, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual IAsyncResult UnsafeBeginMultipleWrite( BufferOffsetSize[] buffers, AsyncCallback callback, Object state) { #if DEBUG GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite"); using (GlobalLog.SetThreadKind(ThreadKinds.Async)) { #endif // // parameter validation // if (buffers == null) { throw new ArgumentNullException("buffers"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { buffers = ConcatenateBuffersOnWin9x(buffers); // // call BeginMultipleSend on the Socket. // IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginMultipleSend( buffers, SocketFlags.None, callback, state); return asyncResult; } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } internal virtual void EndMultipleWrite(IAsyncResult asyncResult) { GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::EndMultipleWrite"); // // parameter validation // if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { chkStreamSocket.EndMultipleSend(asyncResult); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } ////// Starts off an async Write of an array of buffers. /// ////// private BufferOffsetSize[] ConcatenateBuffersOnWin9x(BufferOffsetSize[] buffers) { #if !FEATURE_PAL if (ComNetOS.IsWin9x && buffers.Length > 16) { // We met the limitation of winsock on Win9x // Combine buffers after the 15th into one so overall number does not exceed 16 BufferOffsetSize[] newBuffers = new BufferOffsetSize[16]; int i; for (i = 0; i < 16; ++i) { newBuffers[i] = buffers[i]; } int size = 0; for (i = 15; i < buffers.Length; ++i) { size += buffers[i].Size; } if (size > 0) { newBuffers[15] = new BufferOffsetSize(new byte[size], 0, size, false); for (size = 0, i = 15; i < buffers.Length; size+=buffers[i].Size, ++i) { System.Buffer.BlockCopy(buffers[i].Buffer, buffers[i].Offset, newBuffers[15].Buffer, size, buffers[i].Size); } } buffers = newBuffers; } #endif // !FEATURE_PAL return buffers; } ////// Due to Winsock restrictions /// If on Win9x platforms and the number of buffers are more than 16, performs /// concatenation of the buffers, so that we have 16 buffers. /// ////// public override void Flush() { } ////// Flushes data from the stream. This is meaningless for us, so it does nothing. /// ////// public override void SetLength(long value) { throw new NotSupportedException(SR.GetString(SR.net_noseek)); } int m_CurrentReadTimeout = -1; int m_CurrentWriteTimeout = -1; internal void SetSocketTimeoutOption(SocketShutdown mode, int timeout, bool silent) { GlobalLog.Print("NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption() mode:" + mode + " silent:" + silent + " timeout:" + timeout + " m_CurrentReadTimeout:" + m_CurrentReadTimeout + " m_CurrentWriteTimeout:" + m_CurrentWriteTimeout); GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption"); if (timeout < 0) { timeout = 0; // -1 becomes 0 for the winsock stack } Socket chkStreamSocket = m_StreamSocket; if (chkStreamSocket==null) { return; } if (mode==SocketShutdown.Send || mode==SocketShutdown.Both) { if (timeout!=m_CurrentWriteTimeout) { chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout, silent); m_CurrentWriteTimeout = timeout; } } if (mode==SocketShutdown.Receive || mode==SocketShutdown.Both) { if (timeout!=m_CurrentReadTimeout) { chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout, silent); m_CurrentReadTimeout = timeout; } } } #if TRAVE [System.Diagnostics.Conditional("TRAVE")] internal void Debug() { if (m_StreamSocket != null) { GlobalLog.Print("m_StreamSocket:"); m_StreamSocket.Debug(); } } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007./// Sets the length of the stream. Always throws //////
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- InputReport.cs
- HeaderCollection.cs
- MenuRendererStandards.cs
- MouseButton.cs
- ServicePointManagerElement.cs
- DateTime.cs
- BitConverter.cs
- DBCommandBuilder.cs
- BeginStoryboard.cs
- RegexRunnerFactory.cs
- DataGridColumnHeaderAutomationPeer.cs
- RC2CryptoServiceProvider.cs
- CompiledQuery.cs
- DynamicMethod.cs
- MarshalByRefObject.cs
- DateTimeParse.cs
- WebPartVerbsEventArgs.cs
- Crc32.cs
- TextBox.cs
- _NetRes.cs
- DiscreteKeyFrames.cs
- HttpPostedFile.cs
- ErrorWrapper.cs
- VisualStates.cs
- ValidationSummary.cs
- BufferBuilder.cs
- StylusCollection.cs
- AssemblyCache.cs
- DataListCommandEventArgs.cs
- MSAAEventDispatcher.cs
- IntSecurity.cs
- ModelItemDictionaryImpl.cs
- ConnectionManagementElement.cs
- WebContext.cs
- ReadOnlyObservableCollection.cs
- DataGridViewRowPrePaintEventArgs.cs
- MaterialCollection.cs
- RegularExpressionValidator.cs
- Activator.cs
- ProtocolsConfigurationHandler.cs
- CommentEmitter.cs
- ThicknessAnimationBase.cs
- ToolboxBitmapAttribute.cs
- ConnectionManagementElement.cs
- ScrollItemPatternIdentifiers.cs
- TypeReference.cs
- CompiledXpathExpr.cs
- OleDbError.cs
- ObjectListField.cs
- NavigationService.cs
- WasAdminWrapper.cs
- basecomparevalidator.cs
- DesignerForm.cs
- AQNBuilder.cs
- TraceLevelStore.cs
- ContentFilePart.cs
- TcpWorkerProcess.cs
- RegexCapture.cs
- GridViewCellAutomationPeer.cs
- Timeline.cs
- TextEffectResolver.cs
- CssClassPropertyAttribute.cs
- NativeMethods.cs
- NavigateEvent.cs
- DbConnectionHelper.cs
- SiteMapNodeCollection.cs
- ConfigurationErrorsException.cs
- SkewTransform.cs
- uribuilder.cs
- COAUTHIDENTITY.cs
- CdpEqualityComparer.cs
- RsaSecurityTokenAuthenticator.cs
- SharedUtils.cs
- UrlMappingsSection.cs
- Pen.cs
- OptimalTextSource.cs
- PropertiesTab.cs
- DataGridViewCheckBoxColumn.cs
- TreeNodeSelectionProcessor.cs
- XamlSerializerUtil.cs
- SystemDiagnosticsSection.cs
- Margins.cs
- PolyLineSegmentFigureLogic.cs
- LocalizabilityAttribute.cs
- MenuRenderer.cs
- DataServiceProcessingPipeline.cs
- ZipIOLocalFileBlock.cs
- ListBox.cs
- CodeDomExtensionMethods.cs
- XmlILOptimizerVisitor.cs
- SafeEventLogReadHandle.cs
- ProbeMatchesCD1.cs
- ClientBuildManagerTypeDescriptionProviderBridge.cs
- PowerModeChangedEventArgs.cs
- FormView.cs
- DictionaryKeyPropertyAttribute.cs
- TCPClient.cs
- EnumMemberAttribute.cs
- AggregationMinMaxHelpers.cs
- RetrieveVirtualItemEventArgs.cs