Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / Sockets / NetworkStream.cs / 1305376 / 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;
///
///
/// Provides the underlying stream of data for network access.
///
///
public class NetworkStream : Stream {
///
///
/// Used by the class to hold the underlying socket the stream uses.
///
///
private Socket m_StreamSocket;
///
///
/// Used by the class to indicate that the stream is m_Readable.
///
///
private bool m_Readable;
///
///
/// Used by the class to indicate that the stream is writable.
///
///
private bool m_Writeable;
private bool m_OwnsSocket;
///
/// Creates a new instance of the without initalization.
///
internal NetworkStream() {
m_OwnsSocket = true;
}
// Can be constructed directly out of a socket
///
/// Creates a new instance of the class for the specified .
///
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 with the specified access rights.
///
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);
}
///
///
/// Used by the class to indicate that the stream is m_Readable.
///
///
protected bool Readable {
get {
return m_Readable;
}
set {
m_Readable = value;
}
}
///
///
/// Used by the class to indicate that the stream is writable.
///
///
protected bool Writeable {
get {
return m_Writeable;
}
set {
m_Writeable = value;
}
}
///
///
/// 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 CanRead {
get {
return m_Readable;
}
}
///
///
/// Indicates that the stream can seek a specific location
/// in the stream. This property always returns
/// .
///
///
public override bool CanSeek {
get {
return false;
}
}
///
///
/// Indicates that data can be written to the stream.
///
///
public override bool CanWrite {
get {
return m_Writeable;
}
}
///
/// Indicates whether we can timeout
///
public override bool CanTimeout {
get {
return true; // should we check for Connected state?
}
}
///
/// 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 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("value", SR.GetString(SR.net_io_timeout_use_gt_zero));
}
SetSocketTimeoutOption(SocketShutdown.Receive, 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 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("value", SR.GetString(SR.net_io_timeout_use_gt_zero));
}
SetSocketTimeoutOption(SocketShutdown.Send, value, false);
#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 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
}
}
///
///
/// The length of data available on the stream. Always throws .
///
///
public override long Length {
get {
throw new NotSupportedException(SR.GetString(SR.net_noseek));
}
}
///
///
/// Gets or sets the position in 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));
}
}
///
///
/// Seeks a specific position in the stream. This method is not supported by the
/// class.
///
///
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.
--*/
///
///
/// Reads data from the stream.
///
///
//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.
--*/
///
///
/// Writes data to 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);
}
#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
// 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
}
///
///
/// Indicates whether the stream is still connected
///
///
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.
--*/
///
///
/// Begins an asychronous read from a stream.
///
///
[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);
}
#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);
}
}
/*++
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.
--*/
///
///
/// Handle the end of an asynchronous read.
///
///
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);
}
#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.
--*/
///
///
/// Begins an asynchronous write to a stream.
///
///
[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);
}
#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);
}
#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.
///
///
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);
}
#if DEBUG
}
#endif
}
///
///
/// Performs a [....] Write of an array of buffers.
///
///
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);
}
}
///
///
/// Starts off an async 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);
}
#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);
}
#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);
}
}
///
///
/// 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.
///
///
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;
}
///
///
/// Flushes data from the stream. This is meaningless for us, so it does nothing.
///
///
public override void Flush() {
}
///
///
/// Sets the length of the stream. Always throws
///
///
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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ZipIOLocalFileBlock.cs
- HitTestDrawingContextWalker.cs
- RegexTypeEditor.cs
- TextParaClient.cs
- EditorBrowsableAttribute.cs
- GenericEnumConverter.cs
- TextEndOfLine.cs
- AnnotationAdorner.cs
- ExtensibleClassFactory.cs
- PanelStyle.cs
- RoutedPropertyChangedEventArgs.cs
- StoragePropertyMapping.cs
- MdiWindowListItemConverter.cs
- XmlName.cs
- ControlBuilder.cs
- UnmanagedMemoryStreamWrapper.cs
- ModuleConfigurationInfo.cs
- PageBuildProvider.cs
- Utils.cs
- FixedSOMTextRun.cs
- InputScopeManager.cs
- TemplateBindingExtensionConverter.cs
- RotateTransform.cs
- GridItem.cs
- ComponentSerializationService.cs
- ConnectionManagementSection.cs
- PropertyFilterAttribute.cs
- SynchronizedMessageSource.cs
- Ticks.cs
- LoadRetryStrategyFactory.cs
- ReachIDocumentPaginatorSerializerAsync.cs
- TableRowGroup.cs
- PerformanceCounterManager.cs
- PasswordRecovery.cs
- typedescriptorpermissionattribute.cs
- ComponentGlyph.cs
- VectorCollectionValueSerializer.cs
- PropertySourceInfo.cs
- FormCollection.cs
- SQLInt64.cs
- SafeNativeMethods.cs
- ToolStripTextBox.cs
- HttpModuleActionCollection.cs
- StylusCaptureWithinProperty.cs
- SearchForVirtualItemEventArgs.cs
- InteropAutomationProvider.cs
- AssemblyGen.cs
- XmlQueryCardinality.cs
- SspiSafeHandles.cs
- X500Name.cs
- CompensationParticipant.cs
- HttpListenerRequest.cs
- SeekableReadStream.cs
- CodeDOMUtility.cs
- GlyphingCache.cs
- NCryptNative.cs
- EmptyStringExpandableObjectConverter.cs
- BuildProvider.cs
- ServiceOperationParameter.cs
- FocusWithinProperty.cs
- HMACSHA256.cs
- VersionPair.cs
- FontCacheUtil.cs
- EDesignUtil.cs
- NumericPagerField.cs
- FontCollection.cs
- ColumnTypeConverter.cs
- IDataContractSurrogate.cs
- ListViewInsertionMark.cs
- ToolboxComponentsCreatedEventArgs.cs
- UriSchemeKeyedCollection.cs
- XamlFigureLengthSerializer.cs
- XmlCharCheckingReader.cs
- SoapAttributeAttribute.cs
- EntityConnection.cs
- ClientApiGenerator.cs
- PersistenceContextEnlistment.cs
- unitconverter.cs
- BuildResultCache.cs
- SpecialNameAttribute.cs
- PropertyFilterAttribute.cs
- ToolStripPanelCell.cs
- _IPv4Address.cs
- EventData.cs
- UriTemplateMatchException.cs
- ActivityContext.cs
- TouchDevice.cs
- RtfToXamlLexer.cs
- CodeDelegateInvokeExpression.cs
- MsiStyleLogWriter.cs
- HtmlElementEventArgs.cs
- TextAdaptor.cs
- XmlSchemaObjectTable.cs
- TemplateComponentConnector.cs
- AutomationPeer.cs
- IndexingContentUnit.cs
- DataGridViewTextBoxEditingControl.cs
- ExecutedRoutedEventArgs.cs
- ParallelSeparator.xaml.cs
- CollectionConverter.cs