//
// Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
// http://www.myelin.co.nz
-// (c) 2004-2006 Novell, Inc. (http://www.novell.com)
+// (c) 2004-2011 Novell, Inc. (http://www.novell.com)
//
-
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Net.Configuration;
using System.Text;
using System.Timers;
-#if !MOONLIGHT
using System.Net.NetworkInformation;
-#endif
namespace System.Net.Sockets
{
{
private bool islistening;
private bool useoverlappedIO;
+ private const int SOCKET_CLOSED = 10004;
- static void AddSockets (ArrayList sockets, IList list, string name)
+ private static readonly string timeout_exc_msg = "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond";
+
+ static void AddSockets (List<Socket> sockets, IList list, string name)
{
if (list != null) {
foreach (Socket sock in list) {
#endif
public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
{
- ArrayList list = new ArrayList ();
+ var list = new List<Socket> ();
AddSockets (list, checkRead, "checkRead");
AddSockets (list, checkWrite, "checkWrite");
AddSockets (list, checkError, "checkError");
* WRITE socket 0-n, null,
* ERROR socket 0-n, null
*/
- Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
+ Socket [] sockets = list.ToArray ();
Select_internal (ref sockets, microSeconds, out error);
if (error != 0)
// private constructor used by Accept, which already
// has a socket handle to use
- private Socket(AddressFamily family, SocketType type,
+ internal Socket(AddressFamily family, SocketType type,
ProtocolType proto, IntPtr sock)
{
address_family=family;
}
}
-
- [MonoTODO]
+#if !MOBILE
public Socket (SocketInformation socketInformation)
{
- throw new NotImplementedException ("SocketInformation not figured out yet");
+ var options = socketInformation.Options;
+ islistening = (options & SocketInformationOptions.Listening) != 0;
+ connected = (options & SocketInformationOptions.Connected) != 0;
+ blocking = (options & SocketInformationOptions.NonBlocking) == 0;
+ useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
- // ifdef to avoid the warnings.
-#if false
- //address_family = socketInformation.address_family;
- //socket_type = socketInformation.socket_type;
- //protocol_type = socketInformation.protocol_type;
- address_family = AddressFamily.InterNetwork;
- socket_type = SocketType.Stream;
- protocol_type = ProtocolType.IP;
+ var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
- int error;
- socket = Socket_internal (address_family, socket_type, protocol_type, out error);
- if (error != 0)
- throw new SocketException (error);
-
+ address_family = (AddressFamily) (int) result [0];
+ socket_type = (SocketType) (int) result [1];
+ protocol_type = (ProtocolType) (int) result [2];
+ isbound = (ProtocolType) (int) result [3] != 0;
+ socket = (IntPtr) (long) result [4];
SocketDefaults ();
-#endif
}
-
+#endif
+
#if !TARGET_JVM
// Returns the amount of data waiting to be read on socket
[MethodImplAttribute(MethodImplOptions.InternalCall)]
#if !TARGET_JVM
// Returns the local endpoint details in addr and port
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
+ private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
#endif
// Wish: support non-IP endpoints.
SocketAddress sa;
int error;
- sa=LocalEndPoint_internal(socket, out error);
+ sa=LocalEndPoint_internal(socket, (int) address_family, out error);
if (error != 0)
throw new SocketException (error);
}
}
-#if !MOONLIGHT
public bool AcceptAsync (SocketAsyncEventArgs e)
{
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
}
e.curSocket = this;
- e.Worker.Init (this, null, e.AcceptCallback, SocketOperation.Accept);
- SocketAsyncCall sac = new SocketAsyncCall (e.Worker.Accept);
- sac.BeginInvoke (null, e.Worker.result);
+ Worker w = e.Worker;
+ w.Init (this, e, SocketOperation.Accept);
+ int count;
+ lock (readQ) {
+ readQ.Enqueue (e.Worker);
+ count = readQ.Count;
+ }
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, w.result);
return true;
}
-#endif
-
// Creates a new system socket, returning the handle
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
int error = 0;
IntPtr sock = (IntPtr) (-1);
- blocking_thread = Thread.CurrentThread;
try {
+ RegisterForBlockingSyscall ();
sock = Accept_internal(socket, out error, blocking);
- } catch (ThreadAbortException) {
- if (disposed) {
- Thread.ResetAbort ();
- error = (int) SocketError.Interrupted;
- }
} finally {
- blocking_thread = null;
+ UnRegisterForBlockingSyscall ();
+ }
+
+ if (error != 0) {
+ if (closed)
+ error = SOCKET_CLOSED;
+ throw new SocketException(error);
}
- if (error != 0)
- throw new SocketException (error);
-
Socket accepted = new Socket(this.AddressFamily, this.SocketType,
this.ProtocolType, sock);
int error = 0;
IntPtr sock = (IntPtr)(-1);
- blocking_thread = Thread.CurrentThread;
try {
+ RegisterForBlockingSyscall ();
sock = Accept_internal (socket, out error, blocking);
- } catch (ThreadAbortException) {
- if (disposed) {
- Thread.ResetAbort ();
- error = (int)SocketError.Interrupted;
- }
} finally {
- blocking_thread = null;
+ UnRegisterForBlockingSyscall ();
}
- if (error != 0)
+ if (error != 0) {
+ if (closed)
+ error = SOCKET_CLOSED;
throw new SocketException (error);
+ }
acceptSocket.address_family = this.AddressFamily;
acceptSocket.socket_type = this.SocketType;
throw new InvalidOperationException ();
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
- sac.BeginInvoke (null, req);
- return(req);
+ int count;
+ lock (readQ) {
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
+ }
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
+ return req;
}
public IAsyncResult BeginAccept (int receiveSize,
throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
-
req.Buffer = new byte[receiveSize];
req.Offset = 0;
req.Size = receiveSize;
req.SockFlags = SocketFlags.None;
-
- sac.BeginInvoke (null, req);
- return(req);
+ int count;
+ lock (readQ) {
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
+ }
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
+ return req;
}
public IAsyncResult BeginAccept (Socket acceptSocket,
}
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
-
req.Buffer = new byte[receiveSize];
req.Offset = 0;
req.Size = receiveSize;
req.SockFlags = SocketFlags.None;
req.AcceptSocket = acceptSocket;
-
- sac.BeginInvoke (null, req);
- return(req);
- }
-
- public IAsyncResult BeginConnect(EndPoint end_point,
- AsyncCallback callback,
- object state) {
-
- if (disposed && closed)
- throw new ObjectDisposedException (GetType ().ToString ());
-
- if (end_point == null)
- throw new ArgumentNullException ("end_point");
-
- SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
- req.EndPoint = end_point;
-
- // Bug #75154: Connect() should not succeed for .Any addresses.
- if (end_point is IPEndPoint) {
- IPEndPoint ep = (IPEndPoint) end_point;
- if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
- req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
- return req;
- }
- }
-
- int error = 0;
- if (!blocking) {
- SocketAddress serial = end_point.Serialize ();
- Connect_internal (socket, serial, out error);
- if (error == 0) {
- // succeeded synch
- connected = true;
- req.Complete (true);
- } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
- // error synch
- connected = false;
- req.Complete (new SocketException (error), true);
- }
- }
-
- if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
- // continue asynch
- connected = false;
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
- sac.BeginInvoke (null, req);
+ int count;
+ lock (readQ) {
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
}
-
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
return(req);
}
if (address.ToString ().Length == 0)
throw new ArgumentException ("The length of the IP address is zero");
+ if (port <= 0 || port > 65535)
+ throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
+
if (islistening)
throw new InvalidOperationException ();
return(BeginConnect (iep, callback, state));
}
- public IAsyncResult BeginConnect (IPAddress[] addresses,
- int port,
- AsyncCallback callback,
- object state)
- {
- if (disposed && closed)
- throw new ObjectDisposedException (GetType ().ToString ());
-
- if (addresses == null)
- throw new ArgumentNullException ("addresses");
-
- if (this.AddressFamily != AddressFamily.InterNetwork &&
- this.AddressFamily != AddressFamily.InterNetworkV6)
- throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
-
- if (islistening)
- throw new InvalidOperationException ();
-
- SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
- req.Addresses = addresses;
- req.Port = port;
-
- connected = false;
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
- sac.BeginInvoke (null, req);
-
- return(req);
- }
-
public IAsyncResult BeginConnect (string host, int port,
AsyncCallback callback,
object state)
address_family != AddressFamily.InterNetworkV6)
throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
+ if (port <= 0 || port > 65535)
+ throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
+
if (islistening)
throw new InvalidOperationException ();
- IPAddress [] addresses = Dns.GetHostAddresses (host);
- return (BeginConnect (addresses, port, callback, state));
+ return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
}
public IAsyncResult BeginDisconnect (bool reuseSocket,
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
req.ReuseSocket = reuseSocket;
-
- Worker worker = new Worker (req);
- SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
- sac.BeginInvoke (null, req);
-
+ socket_pool_queue (Worker.Dispatcher, req);
return(req);
}
+
+ void CheckRange (byte[] buffer, int offset, int size)
+ {
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
+
+ if (offset > buffer.Length)
+ throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
+
+ if (size < 0)
+ throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
+
+ if (size > buffer.Length - offset)
+ throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
+ }
public IAsyncResult BeginReceive(byte[] buffer, int offset,
int size,
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
req.Buffer = buffer;
req.Offset = offset;
req.Size = size;
req.SockFlags = socket_flags;
- Worker worker = new Worker (req);
+ int count;
lock (readQ) {
- readQ.Enqueue (worker);
- if (readQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
- sac.BeginInvoke (null, req);
- }
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
}
-
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
return req;
}
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
req.Buffers = buffers;
req.SockFlags = socketFlags;
- Worker worker = new Worker (req);
+ int count;
lock(readQ) {
- readQ.Enqueue (worker);
- if (readQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
- sac.BeginInvoke (null, req);
- }
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
}
-
- return(req);
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
+ return req;
}
[CLSCompliant (false)]
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0)
- throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
- if (size < 0)
- throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
+ if (remote_end == null)
+ throw new ArgumentNullException ("remote_end");
- if (offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+ CheckRange (buffer, offset, size);
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
req.Buffer = buffer;
req.Size = size;
req.SockFlags = socket_flags;
req.EndPoint = remote_end;
- Worker worker = new Worker (req);
+ int count;
lock (readQ) {
- readQ.Enqueue (worker);
- if (readQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
- sac.BeginInvoke (null, req);
- }
+ readQ.Enqueue (req.Worker);
+ count = readQ.Count;
}
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
return req;
}
if (remoteEP == null)
throw new ArgumentNullException ("remoteEP");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
throw new NotImplementedException ();
}
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0)
- throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
- if (size < 0)
- throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
-
- if (offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+ CheckRange (buffer, offset, size);
if (!connected)
throw new SocketException ((int)SocketError.NotConnected);
req.Offset = offset;
req.Size = size;
req.SockFlags = socket_flags;
- Worker worker = new Worker (req);
+ int count;
lock (writeQ) {
- writeQ.Enqueue (worker);
- if (writeQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
- sac.BeginInvoke (null, req);
- }
+ writeQ.Enqueue (req.Worker);
+ count = writeQ.Count;
}
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
return req;
}
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
req.Buffers = buffers;
req.SockFlags = socketFlags;
- Worker worker = new Worker (req);
+ int count;
lock (writeQ) {
- writeQ.Enqueue (worker);
- if (writeQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
- sac.BeginInvoke (null, req);
- }
+ writeQ.Enqueue (req.Worker);
+ count = writeQ.Count;
}
-
- return(req);
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
+ return req;
}
[CLSCompliant (false)]
throw new FileNotFoundException ();
SendFileHandler d = new SendFileHandler (SendFile);
- return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
+ return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, ar => {
+ SendFileAsyncResult sfar = new SendFileAsyncResult (d, ar);
+ callback (sfar);
+ }, state));
}
public IAsyncResult BeginSendTo(byte[] buffer, int offset,
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0)
- throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
- if (size < 0)
- throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
-
- if (offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+ CheckRange (buffer, offset, size);
SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
req.Buffer = buffer;
req.Size = size;
req.SockFlags = socket_flags;
req.EndPoint = remote_end;
- Worker worker = new Worker (req);
+ int count;
lock (writeQ) {
- writeQ.Enqueue (worker);
- if (writeQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
- sac.BeginInvoke (null, req);
- }
+ writeQ.Enqueue (req.Worker);
+ count = writeQ.Count;
}
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, req);
return req;
}
seed_endpoint = local_end;
}
-#if !MOONLIGHT
- public bool ConnectAsync (SocketAsyncEventArgs e)
- {
- // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
-
- if (disposed && closed)
- throw new ObjectDisposedException (GetType ().ToString ());
- if (islistening)
- throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
- if (e.RemoteEndPoint == null)
- throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
- if (e.BufferList != null)
- throw new ArgumentException ("Multiple buffers cannot be used with this method.");
-
- e.DoOperation (SocketAsyncOperation.Connect, this);
-
- // We always return true for now
- return true;
- }
-#endif
-
public void Connect (IPAddress address, int port)
{
Connect (new IPEndPoint (address, port));
Connect (addresses, port);
}
-#if !MOONLIGHT
public bool DisconnectAsync (SocketAsyncEventArgs e)
{
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
throw new ObjectDisposedException (GetType ().ToString ());
e.curSocket = this;
- e.Worker.Init (this, null, e.DisconnectCallback, SocketOperation.Disconnect);
- SocketAsyncCall sac = new SocketAsyncCall (e.Worker.Disconnect);
- sac.BeginInvoke (null, e.Worker.result);
+ e.Worker.Init (this, e, SocketOperation.Disconnect);
+ socket_pool_queue (Worker.Dispatcher, e.Worker.result);
return true;
}
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static void Disconnect_internal(IntPtr sock, bool reuse, out int error);
}
}
- [MonoTODO ("Not implemented")]
+#if !MOBILE
+ [MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
public SocketInformation DuplicateAndClose (int targetProcessId)
{
- /* Need to serialize this socket into a
- * SocketInformation struct, but must study
- * the MS implementation harder to figure out
- * behaviour as documentation is lacking
- */
- throw new NotImplementedException ();
- }
+ var si = new SocketInformation ();
+ si.Options =
+ (islistening ? SocketInformationOptions.Listening : 0) |
+ (connected ? SocketInformationOptions.Connected : 0) |
+ (blocking ? 0 : SocketInformationOptions.NonBlocking) |
+ (useoverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
+
+ si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket);
+ socket = (IntPtr) (-1);
+ return si;
+ }
+#endif
+
public Socket EndAccept (IAsyncResult result)
{
int bytes;
req.CheckIfThrowDelayedException();
}
-#if !MOONLIGHT
public void EndDisconnect (IAsyncResult asyncResult)
{
if (disposed && closed)
req.CheckIfThrowDelayedException ();
}
-#endif
[MonoTODO]
public int EndReceiveMessageFrom (IAsyncResult asyncResult,
ares.Delegate.EndInvoke (ares.Original);
}
-#if !MOONLIGHT
public int EndSendTo (IAsyncResult result)
{
if (disposed && closed)
req.CheckIfThrowDelayedException();
return req.Total;
}
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void GetSocketOption_arr_internal(IntPtr socket,
// See Socket.IOControl, WSAIoctl documentation in MSDN. The
// common options between UNIX and Winsock are FIONREAD,
// FIONBIO and SIOCATMARK. Anything else will depend on the
- // system.
+ // system except SIO_KEEPALIVE_VALS which is properly handled
+ // on both windows and linux.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
byte [] output, out int error);
return result;
}
- [MonoTODO]
public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
{
- /* Probably just needs to mirror the int
- * overload, but more investigation needed.
- */
- throw new NotImplementedException ();
+ return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public int Receive (byte [] buffer)
{
- if (disposed && closed)
- throw new ObjectDisposedException (GetType ().ToString ());
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- SocketError error;
-
- int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
-
- if (error != SocketError.Success)
- throw new SocketException ((int) error);
-
- return ret;
+ return Receive (buffer, SocketFlags.None);
}
public int Receive (byte [] buffer, SocketFlags flags)
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (size < 0 || size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, 0, size);
SocketError error;
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
SocketError error;
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
return Receive_nochecks (buffer, offset, size, flags, out error);
}
-#if !MOONLIGHT
public bool ReceiveFromAsync (SocketAsyncEventArgs e)
{
if (disposed && closed)
throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
e.curSocket = this;
- e.Worker.Init (this, null, e.ReceiveFromCallback, SocketOperation.ReceiveFrom);
+ e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
SocketAsyncResult res = e.Worker.result;
res.Buffer = e.Buffer;
res.Offset = e.Offset;
res.Size = e.Count;
res.EndPoint = e.RemoteEndPoint;
res.SockFlags = e.SocketFlags;
- Worker worker = new Worker (e);
+ int count;
lock (readQ) {
- readQ.Enqueue (worker);
- if (readQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (e.Worker.ReceiveFrom);
- sac.BeginInvoke (null, res);
- }
+ readQ.Enqueue (e.Worker);
+ count = readQ.Count;
}
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, res);
return true;
}
-#endif
public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
{
if (remoteEP == null)
throw new ArgumentNullException ("remoteEP");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
}
connected = false;
else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
if (throwOnError)
- throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
+ throw new SocketException ((int) SocketError.TimedOut, timeout_exc_msg);
error = (int) SocketError.TimedOut;
return 0;
}
if (remoteEP == null)
throw new ArgumentNullException ("remoteEP");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
/* FIXME: figure out how we get hold of the
* IPPacketInformation
if (buf == null)
throw new ArgumentNullException ("buf");
- if (size < 0 || size > buf.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buf, 0, size);
SocketError error;
if (buf == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset > buf.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buf.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buf, offset, size);
SocketError error;
if (buf == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset > buf.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buf.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buf, offset, size);
return Send_nochecks (buf, offset, size, flags, out error);
}
}
}
-#if !MOONLIGHT
public bool SendToAsync (SocketAsyncEventArgs e)
{
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
e.curSocket = this;
- e.Worker.Init (this, null, e.SendToCallback, SocketOperation.SendTo);
+ e.Worker.Init (this, e, SocketOperation.SendTo);
SocketAsyncResult res = e.Worker.result;
res.Buffer = e.Buffer;
res.Offset = e.Offset;
res.Size = e.Count;
res.SockFlags = e.SocketFlags;
res.EndPoint = e.RemoteEndPoint;
- Worker worker = new Worker (e);
+ int count;
lock (writeQ) {
- writeQ.Enqueue (worker);
- if (writeQ.Count == 1) {
- SocketAsyncCall sac = new SocketAsyncCall (e.Worker.SendTo);
- sac.BeginInvoke (null, res);
- }
+ writeQ.Enqueue (e.Worker);
+ count = writeQ.Count;
}
- // We always return true for now
+ if (count == 1)
+ socket_pool_queue (Worker.Dispatcher, res);
return true;
}
-#endif
public int SendTo (byte [] buffer, EndPoint remote_end)
{
if (remote_end == null)
throw new ArgumentNullException ("remote_end");
- if (size < 0 || size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, 0, size);
return SendTo_nochecks (buffer, 0, size, flags, remote_end);
}
if (remote_end == null)
throw new ArgumentNullException("remote_end");
- if (offset < 0 || offset > buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (size < 0 || offset + size > buffer.Length)
- throw new ArgumentOutOfRangeException ("size");
+ CheckRange (buffer, offset, size);
return SendTo_nochecks (buffer, offset, size, flags, remote_end);
}