1 //------------------------------------------------------------------------------
2 // <copyright file="NetworkStream.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Net.Sockets {
9 using System.Runtime.InteropServices;
10 using System.Threading;
11 using System.Security.Permissions;
12 using System.Threading.Tasks;
16 /// Provides the underlying stream of data for network access.
19 public class NetworkStream : Stream {
22 /// Used by the class to hold the underlying socket the stream uses.
25 private Socket m_StreamSocket;
29 /// Used by the class to indicate that the stream is m_Readable.
32 private bool m_Readable;
36 /// Used by the class to indicate that the stream is writable.
39 private bool m_Writeable;
41 private bool m_OwnsSocket;
44 /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> without initalization.</para>
46 internal NetworkStream() {
51 // Can be constructed directly out of a socket
53 /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> class for the specified <see cref='System.Net.Sockets.Socket'/>.</para>
55 public NetworkStream(Socket socket) {
57 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
60 throw new ArgumentNullException("socket");
62 InitNetworkStream(socket, FileAccess.ReadWrite);
68 //UEUE (see FileStream)
69 // ownsHandle: true if the file handle will be owned by this NetworkStream instance; otherwise, false.
70 public NetworkStream(Socket socket, bool ownsSocket) {
72 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
75 throw new ArgumentNullException("socket");
77 InitNetworkStream(socket, FileAccess.ReadWrite);
78 m_OwnsSocket = ownsSocket;
84 internal NetworkStream(NetworkStream networkStream, bool ownsSocket) {
85 Socket socket = networkStream.Socket;
87 throw new ArgumentNullException("networkStream");
89 InitNetworkStream(socket, FileAccess.ReadWrite);
90 m_OwnsSocket = ownsSocket;
93 // Create with a socket and access mode
95 /// <para>Creates a new instance of the <see cref='System.Net.Sockets.NetworkStream'/> class for the specified <see cref='System.Net.Sockets.Socket'/> with the specified access rights.</para>
97 public NetworkStream(Socket socket, FileAccess access) {
99 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
101 if (socket == null) {
102 throw new ArgumentNullException("socket");
104 InitNetworkStream(socket, access);
109 public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) {
111 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
113 if (socket == null) {
114 throw new ArgumentNullException("socket");
116 InitNetworkStream(socket, access);
117 m_OwnsSocket = ownsSocket;
124 // Socket - provides access to socket for stream closing
126 protected Socket Socket {
128 return m_StreamSocket;
132 internal Socket InternalSocket {
134 Socket chkSocket = m_StreamSocket;
135 if (m_CleanedUp || chkSocket == null) {
136 throw new ObjectDisposedException(this.GetType().FullName);
143 internal void InternalAbortSocket()
147 throw new InvalidOperationException();
150 Socket chkSocket = m_StreamSocket;
151 if (m_CleanedUp || chkSocket == null)
160 catch (ObjectDisposedException)
165 internal void ConvertToNotSocketOwner() {
166 m_OwnsSocket = false;
167 // Suppress for finialization still allow proceed the requests
168 GC.SuppressFinalize(this);
173 /// Used by the class to indicate that the stream is m_Readable.
176 protected bool Readable {
187 /// Used by the class to indicate that the stream is writable.
190 protected bool Writeable {
202 /// Indicates that data can be read from the stream.
203 /// We return the readability of this stream. This is a read only property.
206 public override bool CanRead {
215 /// Indicates that the stream can seek a specific location
216 /// in the stream. This property always returns <see langword='false'/>
220 public override bool CanSeek {
229 /// Indicates that data can be written to the stream.
232 public override bool CanWrite {
240 /// <para>Indicates whether we can timeout</para>
242 public override bool CanTimeout {
244 return true; // should we check for Connected state?
250 /// <para>Set/Get ReadTimeout, note of a strange behavior, 0 timeout == infinite for sockets,
251 /// so we map this to -1, and if you set 0, we cannot support it</para>
253 public override int ReadTimeout {
256 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
258 int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
269 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
271 if (value<=0 && value!=System.Threading.Timeout.Infinite) {
272 throw new ArgumentOutOfRangeException("value", SR.GetString(SR.net_io_timeout_use_gt_zero));
274 SetSocketTimeoutOption(SocketShutdown.Receive, value, false);
282 /// <para>Set/Get WriteTimeout, note of a strange behavior, 0 timeout == infinite for sockets,
283 /// so we map this to -1, and if you set 0, we cannot support it</para>
285 public override int WriteTimeout {
288 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
290 int timeout = (int)m_StreamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout);
301 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
303 if (value <= 0 && value != System.Threading.Timeout.Infinite) {
304 throw new ArgumentOutOfRangeException("value", SR.GetString(SR.net_io_timeout_use_gt_zero));
306 SetSocketTimeoutOption(SocketShutdown.Send, value, false);
315 /// Indicates data is available on the stream to be read.
316 /// This property checks to see if at least one byte of data is currently available
319 public virtual bool DataAvailable {
322 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
325 throw new ObjectDisposedException(this.GetType().FullName);
328 Socket chkStreamSocket = m_StreamSocket;
329 if(chkStreamSocket == null) {
330 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
333 // Ask the socket how many bytes are available. If it's
334 // not zero, return true.
336 return chkStreamSocket.Available != 0;
346 /// The length of data available on the stream. Always throws <see cref='NotSupportedException'/>.
349 public override long Length {
351 throw new NotSupportedException(SR.GetString(SR.net_noseek));
357 /// Gets or sets the position in the stream. Always throws <see cref='NotSupportedException'/>.
360 public override long Position {
362 throw new NotSupportedException(SR.GetString(SR.net_noseek));
366 throw new NotSupportedException(SR.GetString(SR.net_noseek));
373 /// Seeks a specific position in the stream. This method is not supported by the
374 /// <see cref='NetworkStream'/> class.
377 public override long Seek(long offset, SeekOrigin origin) {
378 throw new NotSupportedException(SR.GetString(SR.net_noseek));
384 InitNetworkStream - initialize a network stream.
386 This is the common NetworkStream constructor, called whenever a
387 network stream is created. We validate the socket, set a few
388 options, and call our parent's initializer.
392 S - Socket to be used.
393 Access - Access type desired.
398 Nothing, but may throw an exception.
401 internal void InitNetworkStream(Socket socket, FileAccess Access) {
403 // parameter validation
405 if (!socket.Blocking) {
406 throw new IOException(SR.GetString(SR.net_sockets_blocking));
408 if (!socket.Connected) {
409 throw new IOException(SR.GetString(SR.net_notconnected));
411 if (socket.SocketType != SocketType.Stream) {
412 throw new IOException(SR.GetString(SR.net_notstream));
415 m_StreamSocket = socket;
418 case FileAccess.Read:
421 case FileAccess.Write:
424 case FileAccess.ReadWrite:
425 default: // assume FileAccess.ReadWrite
433 internal bool PollRead() {
437 Socket chkStreamSocket = m_StreamSocket;
438 if (chkStreamSocket == null) {
441 return chkStreamSocket.Poll(0, SelectMode.SelectRead);
444 internal bool Poll(int microSeconds, SelectMode mode) {
446 throw new ObjectDisposedException(this.GetType().FullName);
449 Socket chkStreamSocket = m_StreamSocket;
450 if (chkStreamSocket == null) {
451 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
454 return chkStreamSocket.Poll(microSeconds, mode);
459 Read - provide core Read functionality.
461 Provide core read functionality. All we do is call through to the
462 socket Receive functionality.
466 Buffer - Buffer to read into.
467 Offset - Offset into the buffer where we're to read.
468 Count - Number of bytes to read.
472 Number of bytes we read, or 0 if the socket is closed.
478 /// Reads data from the stream.
482 public override int Read([In, Out] byte[] buffer, int offset, int size) {
484 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
486 bool canRead = CanRead; // Prevent race with Dispose.
488 throw new ObjectDisposedException(this.GetType().FullName);
491 throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
494 // parameter validation
497 throw new ArgumentNullException("buffer");
499 if (offset<0 || offset>buffer.Length) {
500 throw new ArgumentOutOfRangeException("offset");
502 if (size<0 || size>buffer.Length-offset) {
503 throw new ArgumentOutOfRangeException("size");
507 Socket chkStreamSocket = m_StreamSocket;
508 if (chkStreamSocket == null) {
509 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
513 int bytesTransferred = chkStreamSocket.Receive(buffer, offset, size, 0);
514 return bytesTransferred;
516 catch (Exception exception) {
517 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
522 // some sort of error occured on the socket call,
523 // set the SocketException as InnerException and throw
525 throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
533 Write - provide core Write functionality.
535 Provide core write functionality. All we do is call through to the
540 Buffer - Buffer to write from.
541 Offset - Offset into the buffer from where we'll start writing.
542 Count - Number of bytes to write.
546 Number of bytes written. We'll throw an exception if we
547 can't write everything. It's brutal, but there's no other
548 way to indicate an error.
553 /// Writes data to the stream..
556 public override void Write(byte[] buffer, int offset, int size) {
558 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
560 bool canWrite = CanWrite; // Prevent race with Dispose.
562 throw new ObjectDisposedException(this.GetType().FullName);
565 throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
568 // parameter validation
571 throw new ArgumentNullException("buffer");
573 if (offset<0 || offset>buffer.Length) {
574 throw new ArgumentOutOfRangeException("offset");
576 if (size<0 || size>buffer.Length-offset) {
577 throw new ArgumentOutOfRangeException("size");
581 Socket chkStreamSocket = m_StreamSocket;
582 if(chkStreamSocket == null) {
583 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
588 // since the socket is in blocking mode this will always complete
589 // after ALL the requested number of bytes was transferred
591 chkStreamSocket.Send(buffer, offset, size, SocketFlags.None);
593 catch (Exception exception) {
594 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
599 // some sort of error occured on the socket call,
600 // set the SocketException as InnerException and throw
602 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
609 private int m_CloseTimeout = Socket.DefaultCloseTimeout; // 1 ms; -1 = respect linger options
611 public void Close(int timeout) {
613 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) {
616 throw new ArgumentOutOfRangeException("timeout");
618 m_CloseTimeout = timeout;
625 private volatile bool m_CleanedUp = false;
626 protected override void Dispose(bool disposing) {
628 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
630 // Mark this as disposed before changing anything else.
631 bool cleanedUp = m_CleanedUp;
633 if (!cleanedUp && disposing) {
635 // only resource we need to free is the network stream, since this
636 // is based on the client socket, closing the stream will cause us
637 // to flush the data to the network, close the stream and (in the
638 // NetoworkStream code) close the socket as well.
640 if (m_StreamSocket!=null) {
645 // if we own the Socket (false by default), close it
646 // ignoring possible exceptions (eg: the user told us
647 // that we own the Socket but it closed at some point of time,
648 // here we would get an ObjectDisposedException)
650 Socket chkStreamSocket = m_StreamSocket;
651 if (chkStreamSocket!=null) {
652 chkStreamSocket.InternalShutdown(SocketShutdown.Both);
653 chkStreamSocket.Close(m_CloseTimeout);
661 base.Dispose(disposing);
666 GlobalLog.SetThreadSource(ThreadKinds.Finalization);
667 // using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) {
677 /// Indicates whether the stream is still connected
680 internal bool Connected {
682 Socket socket = m_StreamSocket;
683 if (!m_CleanedUp && socket !=null && socket.Connected) {
693 BeginRead - provide async read functionality.
695 This method provides async read functionality. All we do is
696 call through to the underlying socket async read.
700 buffer - Buffer to read into.
701 offset - Offset into the buffer where we're to read.
702 size - Number of bytes to read.
706 An IASyncResult, representing the read.
712 /// Begins an asychronous read from a stream.
715 [HostProtection(ExternalThreading=true)]
716 public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
718 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
720 bool canRead = CanRead; // Prevent race with Dispose.
722 throw new ObjectDisposedException(this.GetType().FullName);
725 throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
728 // parameter validation
731 throw new ArgumentNullException("buffer");
733 if (offset<0 || offset>buffer.Length) {
734 throw new ArgumentOutOfRangeException("offset");
736 if (size<0 || size>buffer.Length-offset) {
737 throw new ArgumentOutOfRangeException("size");
740 Socket chkStreamSocket = m_StreamSocket;
741 if(chkStreamSocket == null) {
742 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
746 IAsyncResult asyncResult =
747 chkStreamSocket.BeginReceive(
757 catch (Exception exception) {
758 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
763 // some sort of error occured on the socket call,
764 // set the SocketException as InnerException and throw
766 throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
773 internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state)
775 bool canRead = CanRead; // Prevent race with Dispose.
778 throw new ObjectDisposedException(GetType().FullName);
782 throw new InvalidOperationException(SR.GetString(SR.net_writeonlystream));
785 Socket chkStreamSocket = m_StreamSocket;
786 if (chkStreamSocket == null)
788 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
793 IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginReceive(
803 catch (Exception exception)
805 if (NclUtilities.IsFatal(exception)) throw;
808 // some sort of error occured on the socket call,
809 // set the SocketException as InnerException and throw
811 throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
816 EndRead - handle the end of an async read.
818 This method is called when an async read is completed. All we
819 do is call through to the core socket EndReceive functionality.
822 buffer - Buffer to read into.
823 offset - Offset into the buffer where we're to read.
824 size - Number of bytes to read.
828 The number of bytes read. May throw an exception.
834 /// Handle the end of an asynchronous read.
837 public override int EndRead(IAsyncResult asyncResult) {
839 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
842 throw new ObjectDisposedException(this.GetType().FullName);
846 // parameter validation
848 if (asyncResult==null) {
849 throw new ArgumentNullException("asyncResult");
852 Socket chkStreamSocket = m_StreamSocket;
853 if(chkStreamSocket == null) {
854 throw new IOException(SR.GetString(SR.net_io_readfailure, SR.GetString(SR.net_io_connectionclosed)));
858 int bytesTransferred = chkStreamSocket.EndReceive(asyncResult);
859 return bytesTransferred;
861 catch (Exception exception) {
862 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
867 // some sort of error occured on the socket call,
868 // set the SocketException as InnerException and throw
870 throw new IOException(SR.GetString(SR.net_io_readfailure, exception.Message), exception);
878 BeginWrite - provide async write functionality.
880 This method provides async write functionality. All we do is
881 call through to the underlying socket async send.
885 buffer - Buffer to write into.
886 offset - Offset into the buffer where we're to write.
887 size - Number of bytes to written.
891 An IASyncResult, representing the write.
897 /// Begins an asynchronous write to a stream.
900 [HostProtection(ExternalThreading=true)]
901 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
903 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
905 bool canWrite = CanWrite; // Prevent race with Dispose.
907 throw new ObjectDisposedException(this.GetType().FullName);
910 throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
913 // parameter validation
916 throw new ArgumentNullException("buffer");
918 if (offset<0 || offset>buffer.Length) {
919 throw new ArgumentOutOfRangeException("offset");
921 if (size<0 || size>buffer.Length-offset) {
922 throw new ArgumentOutOfRangeException("size");
925 Socket chkStreamSocket = m_StreamSocket;
926 if(chkStreamSocket == null) {
927 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
932 // call BeginSend on the Socket.
934 IAsyncResult asyncResult =
935 chkStreamSocket.BeginSend(
945 catch (Exception exception) {
946 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
951 // some sort of error occured on the socket call,
952 // set the SocketException as InnerException and throw
954 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
963 internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
965 using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) {
967 bool canWrite = CanWrite; // Prevent race with Dispose.
969 throw new ObjectDisposedException(this.GetType().FullName);
973 throw new InvalidOperationException(SR.GetString(SR.net_readonlystream));
976 Socket chkStreamSocket = m_StreamSocket;
977 if(chkStreamSocket == null) {
978 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
983 // call BeginSend on the Socket.
985 IAsyncResult asyncResult =
986 chkStreamSocket.UnsafeBeginSend(
996 catch (Exception exception) {
997 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1002 // some sort of error occured on the socket call,
1003 // set the SocketException as InnerException and throw
1005 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1016 /// Handle the end of an asynchronous write.
1017 /// This method is called when an async write is completed. All we
1018 /// do is call through to the core socket EndSend functionality.
1019 /// Returns: The number of bytes read. May throw an exception.
1022 public override void EndWrite(IAsyncResult asyncResult) {
1024 using (GlobalLog.SetThreadKind(ThreadKinds.User)) {
1027 throw new ObjectDisposedException(this.GetType().FullName);
1031 // parameter validation
1033 if (asyncResult==null) {
1034 throw new ArgumentNullException("asyncResult");
1037 Socket chkStreamSocket = m_StreamSocket;
1038 if(chkStreamSocket == null) {
1039 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
1043 chkStreamSocket.EndSend(asyncResult);
1045 catch (Exception exception) {
1046 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1051 // some sort of error occured on the socket call,
1052 // set the SocketException as InnerException and throw
1054 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1064 /// Performs a [....] Write of an array of buffers.
1067 internal virtual void MultipleWrite(BufferOffsetSize[] buffers)
1069 GlobalLog.ThreadContract(ThreadKinds.Sync, "NetworkStream#" + ValidationHelper.HashString(this) + "::MultipleWrite");
1072 // parameter validation
1074 if (buffers == null) {
1075 throw new ArgumentNullException("buffers");
1078 Socket chkStreamSocket = m_StreamSocket;
1079 if(chkStreamSocket == null) {
1080 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
1085 chkStreamSocket.MultipleSend(
1090 catch (Exception exception) {
1091 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1096 // some sort of error occured on the socket call,
1097 // set the SocketException as InnerException and throw
1099 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1106 /// Starts off an async Write of an array of buffers.
1109 internal virtual IAsyncResult BeginMultipleWrite(
1110 BufferOffsetSize[] buffers,
1111 AsyncCallback callback,
1115 GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite");
1116 using (GlobalLog.SetThreadKind(ThreadKinds.Async)) {
1120 // parameter validation
1122 if (buffers == null) {
1123 throw new ArgumentNullException("buffers");
1126 Socket chkStreamSocket = m_StreamSocket;
1127 if(chkStreamSocket == null) {
1128 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
1134 // call BeginMultipleSend on the Socket.
1136 IAsyncResult asyncResult =
1137 chkStreamSocket.BeginMultipleSend(
1145 catch (Exception exception) {
1147 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1152 // some sort of error occured on the socket call,
1153 // set the SocketException as InnerException and throw
1155 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1163 internal virtual IAsyncResult UnsafeBeginMultipleWrite(
1164 BufferOffsetSize[] buffers,
1165 AsyncCallback callback,
1169 GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::BeginMultipleWrite");
1170 using (GlobalLog.SetThreadKind(ThreadKinds.Async)) {
1174 // parameter validation
1176 if (buffers == null) {
1177 throw new ArgumentNullException("buffers");
1180 Socket chkStreamSocket = m_StreamSocket;
1181 if(chkStreamSocket == null) {
1182 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
1188 // call BeginMultipleSend on the Socket.
1190 IAsyncResult asyncResult =
1191 chkStreamSocket.UnsafeBeginMultipleSend(
1199 catch (Exception exception) {
1201 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1206 // some sort of error occured on the socket call,
1207 // set the SocketException as InnerException and throw
1209 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1217 internal virtual void EndMultipleWrite(IAsyncResult asyncResult) {
1218 GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::EndMultipleWrite");
1221 // parameter validation
1223 if (asyncResult == null) {
1224 throw new ArgumentNullException("asyncResult");
1227 Socket chkStreamSocket = m_StreamSocket;
1228 if(chkStreamSocket == null) {
1229 throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed)));
1233 chkStreamSocket.EndMultipleSend(asyncResult);
1235 catch (Exception exception) {
1236 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
1241 // some sort of error occured on the socket call,
1242 // set the SocketException as InnerException and throw
1244 throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception);
1250 /// Flushes data from the stream. This is meaningless for us, so it does nothing.
1253 public override void Flush() {
1256 public override Task FlushAsync(CancellationToken cancellationToken)
1258 return Task.CompletedTask;
1263 /// Sets the length of the stream. Always throws <see cref='NotSupportedException'/>
1266 public override void SetLength(long value) {
1267 throw new NotSupportedException(SR.GetString(SR.net_noseek));
1270 int m_CurrentReadTimeout = -1;
1271 int m_CurrentWriteTimeout = -1;
1272 internal void SetSocketTimeoutOption(SocketShutdown mode, int timeout, bool silent) {
1273 GlobalLog.Print("NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption() mode:" + mode + " silent:" + silent + " timeout:" + timeout + " m_CurrentReadTimeout:" + m_CurrentReadTimeout + " m_CurrentWriteTimeout:" + m_CurrentWriteTimeout);
1274 GlobalLog.ThreadContract(ThreadKinds.Unknown, "NetworkStream#" + ValidationHelper.HashString(this) + "::SetSocketTimeoutOption");
1277 timeout = 0; // -1 becomes 0 for the winsock stack
1280 Socket chkStreamSocket = m_StreamSocket;
1281 if (chkStreamSocket==null) {
1284 if (mode==SocketShutdown.Send || mode==SocketShutdown.Both) {
1285 if (timeout!=m_CurrentWriteTimeout) {
1286 chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout, silent);
1287 m_CurrentWriteTimeout = timeout;
1290 if (mode==SocketShutdown.Receive || mode==SocketShutdown.Both) {
1291 if (timeout!=m_CurrentReadTimeout) {
1292 chkStreamSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout, silent);
1293 m_CurrentReadTimeout = timeout;
1299 [System.Diagnostics.Conditional("TRAVE")]
1300 internal void DebugMembers() {
1301 if (m_StreamSocket != null) {
1302 GlobalLog.Print("m_StreamSocket:");
1303 m_StreamSocket.DebugMembers();