Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / Sockets / NetworkStream.cs / 3 / 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.Sync)) { #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.Sync)) { #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.Sync)) { #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 // ignoring 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.Sync, "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 sync 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 } }/// Sets the length of the stream. Always throws //////
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TcpClientSocketManager.cs
- PropertyMetadata.cs
- DeploymentSectionCache.cs
- EtwTrace.cs
- SpeechUI.cs
- StrokeDescriptor.cs
- ServiceHostFactory.cs
- ParserStreamGeometryContext.cs
- WebConfigurationFileMap.cs
- HashJoinQueryOperatorEnumerator.cs
- ElementUtil.cs
- ToggleButton.cs
- SelectionItemPatternIdentifiers.cs
- ObjectViewEntityCollectionData.cs
- LinqDataSourceUpdateEventArgs.cs
- Command.cs
- Region.cs
- WebUtil.cs
- CmsInterop.cs
- SectionRecord.cs
- DesignerAutoFormatCollection.cs
- GrowingArray.cs
- CompoundFileDeflateTransform.cs
- BamlRecords.cs
- AnimatedTypeHelpers.cs
- WindowsTitleBar.cs
- HandleCollector.cs
- Transform.cs
- SafeEventLogWriteHandle.cs
- CodeArrayIndexerExpression.cs
- CalendarItem.cs
- BrowserCapabilitiesCompiler.cs
- VisualStyleTypesAndProperties.cs
- Decoder.cs
- PackWebRequest.cs
- DirectionalLight.cs
- XsltOutput.cs
- TagPrefixInfo.cs
- PackagePart.cs
- ModifierKeysValueSerializer.cs
- EventHandlersDesigner.cs
- TrustManagerMoreInformation.cs
- ProcessingInstructionAction.cs
- securitycriticaldataformultiplegetandset.cs
- DataObjectAttribute.cs
- WrapPanel.cs
- BinaryEditor.cs
- AppSettings.cs
- XamlWriter.cs
- ClientScriptManager.cs
- RelatedImageListAttribute.cs
- ContextMenuStripActionList.cs
- NativeMethodsOther.cs
- InputElement.cs
- WebServiceHost.cs
- ISFTagAndGuidCache.cs
- ObjectDataSource.cs
- RegexRunnerFactory.cs
- ToolBarButtonDesigner.cs
- EncoderBestFitFallback.cs
- COM2PropertyDescriptor.cs
- MenuItemCollection.cs
- WinInetCache.cs
- DesignerLinkAdapter.cs
- ScriptResourceAttribute.cs
- BitmapFrame.cs
- TaiwanCalendar.cs
- ContractUtils.cs
- ChtmlImageAdapter.cs
- DataPointer.cs
- PrtTicket_Base.cs
- ImageField.cs
- RegexRunnerFactory.cs
- AttachedAnnotation.cs
- base64Transforms.cs
- entitydatasourceentitysetnameconverter.cs
- TimeoutException.cs
- TypedTableHandler.cs
- ContentElement.cs
- HtmlInputSubmit.cs
- PriorityQueue.cs
- ScrollBar.cs
- GridLengthConverter.cs
- WorkflowOperationContext.cs
- ChannelSinkStacks.cs
- DefaultBindingPropertyAttribute.cs
- TemplateControlBuildProvider.cs
- BitmapMetadataBlob.cs
- SHA256Managed.cs
- DisplayMemberTemplateSelector.cs
- VectorCollectionConverter.cs
- ByteStreamGeometryContext.cs
- SamlAudienceRestrictionCondition.cs
- KeyConverter.cs
- HttpEncoderUtility.cs
- Vector3D.cs
- ContactManager.cs
- RIPEMD160Managed.cs
- ValidationEventArgs.cs
- SecurityKeyType.cs