//
// Author:
// Miguel de Icaza (miguel@ximian.com)
+// Sridhar Kulkarni <sridharkulkarni@gmail.com>
//
// (C) 2002 Ximian, Inc. http://www.ximian.com
+// Copyright (C) 2002-2006 Novell, Inc. http://www.novell.com
//
//
using System.IO;
using System.Runtime.InteropServices;
+#if !NET_2_1 || MOBILE
+using System.Timers;
+using System.Threading;
+#endif
namespace System.Net.Sockets
{
{
}
- public NetworkStream (Socket socket, bool owns_socket)
- : this (socket, FileAccess.ReadWrite, owns_socket)
+ public NetworkStream (Socket socket, bool ownsSocket)
+ : this (socket, FileAccess.ReadWrite, ownsSocket)
{
}
{
}
- public NetworkStream (Socket socket, FileAccess access, bool owns_socket)
+ public NetworkStream (Socket socket, FileAccess access, bool ownsSocket)
{
if (socket == null)
throw new ArgumentNullException ("socket is null");
- if (!socket.Connected)
- throw new ArgumentException ("Not connected", "socket");
if (socket.SocketType != SocketType.Stream)
throw new ArgumentException ("Socket is not of type Stream", "socket");
+ if (!socket.Connected)
+ throw new IOException ("Not connected");
if (!socket.Blocking)
throw new IOException ("Operation not allowed on a non-blocking socket.");
this.socket = socket;
- this.owns_socket = owns_socket;
+ this.owns_socket = ownsSocket;
this.access = access;
readable = CanRead;
}
}
+ public override bool CanTimeout
+ {
+ get {
+ return(true);
+ }
+ }
+
public override bool CanWrite {
get {
return access == FileAccess.ReadWrite || access == FileAccess.Write;
}
}
+#if !NET_2_1 || MOBILE
+#if TARGET_JVM
+ [MonoNotSupported ("Not supported since Socket.ReceiveTimeout is not supported")]
+#endif
+ public override int ReadTimeout
+ {
+ get {
+ int r = socket.ReceiveTimeout;
+ return (r <= 0) ? Timeout.Infinite : r;
+ }
+ set {
+ if (value <= 0 && value != Timeout.Infinite) {
+ throw new ArgumentOutOfRangeException ("value", "The value specified is less than or equal to zero and is not Infinite.");
+ }
+
+ socket.ReceiveTimeout = value;
+ }
+ }
+#endif
+
protected Socket Socket {
get {
return socket;
}
}
+#if !NET_2_1 || MOBILE
+#if TARGET_JVM
+ [MonoNotSupported ("Not supported since Socket.SendTimeout is not supported")]
+#endif
+ public override int WriteTimeout
+ {
+ get {
+ int r = socket.SendTimeout;
+ return (r <= 0) ? Timeout.Infinite : r;
+ }
+ set {
+ if (value <= 0 && value != Timeout.Infinite) {
+ throw new ArgumentOutOfRangeException ("value", "The value specified is less than or equal to zero and is not Infinite");
+ }
+
+ socket.SendTimeout = value;
+ }
+ }
+#endif
+
public override IAsyncResult BeginRead (byte [] buffer, int offset, int size,
AsyncCallback callback, object state)
{
throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
}
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
- retval = socket.BeginReceive (buffer, offset, size, 0, callback, state);
+ retval = s.BeginReceive (buffer, offset, size, 0, callback, state);
} catch (Exception e) {
throw new IOException ("BeginReceive failure", e);
}
throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
}
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
- retval = socket.BeginSend (buffer, offset, size, 0, callback, state);
+ retval = s.BeginSend (buffer, offset, size, 0, callback, state);
} catch {
throw new IOException ("BeginWrite failure");
}
Dispose (false);
}
- public override void Close ()
+
+#if !NET_2_1 || MOBILE
+ public void Close (int timeout)
{
- ((IDisposable) this).Dispose ();
+ if (timeout < -1) {
+ throw new ArgumentOutOfRangeException ("timeout", "timeout is less than -1");
+ }
+
+ System.Timers.Timer close_timer = new System.Timers.Timer ();
+ close_timer.Elapsed += new ElapsedEventHandler (OnTimeoutClose);
+ /* NB timeout is in milliseconds here, cf
+ * seconds in Socket.Close(int)
+ */
+ close_timer.Interval = timeout;
+ close_timer.AutoReset = false;
+ close_timer.Enabled = true;
+ }
+
+ private void OnTimeoutClose (object source, ElapsedEventArgs e)
+ {
+ this.Close ();
}
-
- protected
-#if NET_2_0
- override
-#else
- virtual
#endif
- void Dispose (bool disposing)
+
+ protected override void Dispose (bool disposing)
{
if (disposed)
return;
s.Close ();
}
socket = null;
+ access = 0;
+
+ if (disposing)
+ GC.SuppressFinalize (this);
}
public override int EndRead (IAsyncResult ar)
if (ar == null)
throw new ArgumentNullException ("async result is null");
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
- res = socket.EndReceive (ar);
+ res = s.EndReceive (ar);
} catch (Exception e) {
throw new IOException ("EndRead failure", e);
}
if (ar == null)
throw new ArgumentNullException ("async result is null");
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
- socket.EndSend (ar);
+ s.EndSend (ar);
} catch (Exception e) {
throw new IOException ("EndWrite failure", e);
}
// network streams are non-buffered, this is a no-op
}
- void IDisposable.Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this);
- }
-
public override int Read ([In,Out] byte [] buffer, int offset, int size)
{
CheckDisposed ();
throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
}
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
- res = socket.Receive (buffer, offset, size, 0);
+ res = s.Receive (buffer, offset, size, 0);
} catch (Exception e) {
throw new IOException ("Read failure", e);
}
if (size < 0 || size > buffer.Length - offset)
throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
+ Socket s = socket;
+
+ if (s == null) {
+ throw new IOException("Connection closed");
+ }
+
try {
int count = 0;
while (size - count > 0) {
- count += socket.Send (buffer, offset + count, size - count, 0);
+ count += s.Send (buffer, offset + count, size - count, 0);
}
} catch (Exception e) {
throw new IOException ("Write failure", e);