1 // System.Net.Sockets.Socket.cs
4 // Phillip Pearson (pp@myelin.co.nz)
5 // Dick Porter <dick@ximian.com>
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Sridhar Kulkarni (sridharkulkarni@gmail.com)
8 // Brian Nickel (brian.nickel@gmail.com)
10 // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
11 // http://www.myelin.co.nz
12 // (c) 2004-2006 Novell, Inc. (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 using System.Collections;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Threading;
42 using System.Reflection;
44 using System.Net.Configuration;
48 using System.Collections.Generic;
49 using System.Net.NetworkInformation;
55 namespace System.Net.Sockets
57 public partial class Socket : IDisposable
59 enum SocketOperation {
76 [StructLayout (LayoutKind.Sequential)]
83 [StructLayout (LayoutKind.Sequential)]
84 private sealed class SocketAsyncResult: IAsyncResult
86 /* Same structure in the runtime */
88 Keep this in sync with MonoSocketAsyncResult in
89 metadata/socket-io.h and ProcessAsyncReader
90 in System.Diagnostics/Process.cs.
96 AsyncCallback callback;
97 WaitHandle waithandle;
99 Exception delayedException;
101 public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
102 public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
103 public int Offset; // Receive,ReceiveFrom,Send,SendTo
104 public int Size; // Receive,ReceiveFrom,Send,SendTo
105 public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
106 public Socket AcceptSocket; // AcceptReceive
107 public IPAddress[] Addresses; // Connect
108 public int Port; // Connect
110 public IList<ArraySegment<byte>> Buffers; // Receive, Send
112 public object Buffers; // Reserve this slot in older profiles
114 public bool ReuseSocket; // Disconnect
122 public bool blocking;
124 SocketOperation operation;
126 public int EndCalled;
128 public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
131 this.blocking = sock.blocking;
132 this.handle = sock.socket;
134 this.callback = callback;
135 this.operation = operation;
136 SockFlags = SocketFlags.None;
139 public void CheckIfThrowDelayedException ()
141 if (delayedException != null) {
142 Sock.connected = false;
143 throw delayedException;
147 Sock.connected = false;
148 throw new SocketException (error);
152 void CompleteAllOnDispose (Queue queue)
154 object [] pending = queue.ToArray ();
158 for (int i = 0; i < pending.Length; i++) {
159 SocketAsyncResult ares = (SocketAsyncResult) pending [i];
160 cb = new WaitCallback (ares.CompleteDisposed);
161 ThreadPool.QueueUserWorkItem (cb, null);
163 if (pending.Length == 0)
167 void CompleteDisposed (object unused)
172 public void Complete ()
174 if (operation != SocketOperation.Receive && Sock.disposed)
175 delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
180 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
182 } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
187 SocketAsyncCall sac = null;
188 SocketAsyncResult req = null;
190 queue.Dequeue (); // remove ourselves
191 if (queue.Count > 0) {
192 req = (SocketAsyncResult) queue.Peek ();
193 if (!Sock.disposed) {
194 Worker worker = new Worker (req);
195 sac = GetDelegate (worker, req.operation);
197 CompleteAllOnDispose (queue);
203 sac.BeginInvoke (null, req);
206 if (callback != null)
211 SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
214 case SocketOperation.Receive:
215 return new SocketAsyncCall (worker.Receive);
216 case SocketOperation.ReceiveFrom:
217 return new SocketAsyncCall (worker.ReceiveFrom);
218 case SocketOperation.Send:
219 return new SocketAsyncCall (worker.Send);
220 case SocketOperation.SendTo:
221 return new SocketAsyncCall (worker.SendTo);
223 return null; // never happens
227 public void Complete (bool synch)
229 completed_sync = synch;
233 public void Complete (int total)
239 public void Complete (Exception e, bool synch)
241 completed_sync = synch;
242 delayedException = e;
246 public void Complete (Exception e)
248 delayedException = e;
252 public void Complete (Socket s)
258 public void Complete (Socket s, int total)
265 public object AsyncState {
271 public WaitHandle AsyncWaitHandle {
274 if (waithandle == null)
275 waithandle = new ManualResetEvent (completed);
285 public bool CompletedSynchronously {
287 return(completed_sync);
291 public bool IsCompleted {
298 if (waithandle != null && value) {
299 ((ManualResetEvent) waithandle).Set ();
305 public Socket Socket {
312 get { return total; }
313 set { total = value; }
316 public SocketError ErrorCode
320 SocketException ex = delayedException as SocketException;
323 return(ex.SocketErrorCode);
326 return((SocketError)error);
328 return(SocketError.Success);
333 private sealed class Worker
335 SocketAsyncResult result;
337 public Worker (SocketAsyncResult ares)
342 public void Accept ()
344 Socket acc_socket = null;
346 acc_socket = result.Sock.Accept ();
347 } catch (Exception e) {
352 result.Complete (acc_socket);
355 /* only used in 2.0 profile and newer, but
356 * leave in older profiles to keep interface
357 * to runtime consistent
359 public void AcceptReceive ()
361 Socket acc_socket = null;
364 if (result.AcceptSocket == null) {
365 acc_socket = result.Sock.Accept ();
367 acc_socket = result.AcceptSocket;
368 result.Sock.Accept (acc_socket);
370 } catch (Exception e) {
375 /* It seems the MS runtime
376 * special-cases 0-length requested
377 * receive data. See bug 464201.
380 if (result.Size > 0) {
384 total = acc_socket.Receive_nochecks (result.Buffer,
389 } catch (Exception e) {
395 result.Complete (acc_socket, total);
398 public void Connect ()
400 /* If result.EndPoint is non-null,
401 * this is the standard one-address
402 * connect attempt. Otherwise
403 * Addresses must be non-null and
404 * contain a list of addresses to try
405 * to connect to; the first one to
406 * succeed causes the rest of the list
409 if (result.EndPoint != null) {
411 if (!result.Sock.Blocking) {
413 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
415 result.Sock.connected = true;
417 result.Complete (new SocketException (success));
421 result.Sock.seed_endpoint = result.EndPoint;
422 result.Sock.Connect (result.EndPoint);
423 result.Sock.connected = true;
425 } catch (Exception e) {
431 } else if (result.Addresses != null) {
432 foreach(IPAddress address in result.Addresses) {
433 IPEndPoint iep = new IPEndPoint (address, result.Port);
434 SocketAddress serial = iep.Serialize ();
437 Socket.Connect_internal (result.Sock.socket, serial, out error);
439 result.Sock.connected = true;
440 result.Sock.seed_endpoint = iep;
443 } else if (error != (int)SocketError.InProgress &&
444 error != (int)SocketError.WouldBlock) {
448 if (!result.Sock.Blocking) {
450 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
452 result.Sock.connected = true;
453 result.Sock.seed_endpoint = iep;
460 result.Complete (new SocketException ((int)SocketError.InProgress));
462 result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
466 /* Also only used in 2.0 profile and newer */
467 public void Disconnect ()
471 result.Sock.Disconnect (result.ReuseSocket);
472 } catch (Exception e) {
478 result.Complete (new SocketException ((int)SocketError.Fault));
482 public void Receive ()
484 // Actual recv() done in the runtime
488 public void ReceiveFrom ()
492 total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
496 ref result.EndPoint);
497 } catch (Exception e) {
502 result.Complete (total);
505 public void ReceiveGeneric ()
512 total = result.Sock.Receive (result.Buffers, result.SockFlags, out error);
513 } catch (Exception e) {
518 result.Complete (total);
520 result.Complete (new SocketException ((int)SocketError.Fault));
526 void UpdateSendValues (int last_sent)
528 if (result.error == 0) {
529 send_so_far += last_sent;
530 result.Offset += last_sent;
531 result.Size -= last_sent;
537 // Actual send() done in the runtime
538 if (result.error == 0) {
539 UpdateSendValues (result.Total);
540 if (result.Sock.disposed) {
545 if (result.Size > 0) {
546 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
547 sac.BeginInvoke (null, result);
548 return; // Have to finish writing everything. See bug #74475.
550 result.Total = send_so_far;
555 public void SendTo ()
559 total = result.Sock.SendTo_nochecks (result.Buffer,
565 UpdateSendValues (total);
566 if (result.Size > 0) {
567 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
568 sac.BeginInvoke (null, result);
569 return; // Have to finish writing everything. See bug #74475.
571 result.Total = send_so_far;
572 } catch (Exception e) {
580 public void SendGeneric ()
587 total = result.Sock.Send (result.Buffers, result.SockFlags, out error);
588 } catch (Exception e) {
593 result.Complete (total);
595 result.Complete (new SocketException ((int)SocketError.Fault));
601 private Queue readQ = new Queue (2);
602 private Queue writeQ = new Queue (2);
604 delegate void SocketAsyncCall ();
607 private bool islistening;
608 private bool useoverlappedIO;
612 static void AddSockets (ArrayList sockets, IList list, string name)
615 foreach (Socket sock in list) {
616 if (sock == null) // MS throws a NullRef
617 throw new ArgumentNullException ("name", "Contains a null element");
625 [MethodImplAttribute(MethodImplOptions.InternalCall)]
626 private extern static void Select_internal (ref Socket [] sockets,
630 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
632 ArrayList list = new ArrayList ();
633 AddSockets (list, checkRead, "checkRead");
634 AddSockets (list, checkWrite, "checkWrite");
635 AddSockets (list, checkError, "checkError");
637 if (list.Count == 3) {
638 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
639 "All the lists are null or empty.");
644 * The 'sockets' array contains: READ socket 0-n, null,
645 * WRITE socket 0-n, null,
646 * ERROR socket 0-n, null
648 Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
649 Select_internal (ref sockets, microSeconds, out error);
652 throw new SocketException (error);
654 if (sockets == null) {
655 if (checkRead != null)
657 if (checkWrite != null)
659 if (checkError != null)
665 int count = sockets.Length;
666 IList currentList = checkRead;
668 for (int i = 0; i < count; i++) {
670 Socket sock = sockets [i];
671 if (sock == null) { // separator
672 if (currentList != null) {
673 // Remove non-signaled sockets after the current one
674 int to_remove = currentList.Count - currentIdx;
675 for (int k = 0; k < to_remove; k++)
676 currentList.RemoveAt (currentIdx);
678 currentList = (mode == 0) ? checkWrite : checkError;
684 if (mode == 1 && currentList == checkWrite && !sock.connected) {
685 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
686 sock.connected = true;
689 // Remove non-signaled sockets before the current one
690 int max = currentList.Count;
691 while ((cur_sock = (Socket) currentList [currentIdx]) != sock) {
692 currentList.RemoveAt (currentIdx);
698 // private constructor used by Accept, which already
699 // has a socket handle to use
700 private Socket(AddressFamily family, SocketType type,
701 ProtocolType proto, IntPtr sock)
703 address_family=family;
711 private void SocketDefaults ()
715 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
716 address_family == AddressFamily.InterNetworkV6 */) {
717 /* This is the default, but it
718 * probably has nasty side
719 * effects on Linux, as the
720 * socket option is kludged by
721 * turning on or off PMTU
724 this.DontFragment = false;
728 // Microsoft sets these to 8192, but we are going to keep them
729 // both to the OS defaults as these have a big performance impact.
730 // on WebClient performance.
732 //this.ReceiveBufferSize = 8192;
733 //this.SendBufferSize = 8192;
734 } catch (SocketException) {
742 public Socket (SocketInformation socketInformation)
744 throw new NotImplementedException ("SocketInformation not figured out yet");
746 // ifdef to avoid the warnings.
748 //address_family = socketInformation.address_family;
749 //socket_type = socketInformation.socket_type;
750 //protocol_type = socketInformation.protocol_type;
751 address_family = AddressFamily.InterNetwork;
752 socket_type = SocketType.Stream;
753 protocol_type = ProtocolType.IP;
756 socket = Socket_internal (address_family, socket_type, protocol_type, out error);
758 throw new SocketException (error);
766 // Returns the amount of data waiting to be read on socket
767 [MethodImplAttribute(MethodImplOptions.InternalCall)]
768 private extern static int Available_internal(IntPtr socket, out int error);
771 public int Available {
773 if (disposed && closed)
774 throw new ObjectDisposedException (GetType ().ToString ());
778 ret = Available_internal(socket, out error);
781 throw new SocketException (error);
789 public bool DontFragment {
791 if (disposed && closed) {
792 throw new ObjectDisposedException (GetType ().ToString ());
797 if (address_family == AddressFamily.InterNetwork) {
798 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
799 } else if (address_family == AddressFamily.InterNetworkV6) {
800 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
802 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
805 return(dontfragment);
808 if (disposed && closed) {
809 throw new ObjectDisposedException (GetType ().ToString ());
812 if (address_family == AddressFamily.InterNetwork) {
813 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
814 } else if (address_family == AddressFamily.InterNetworkV6) {
815 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
817 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
822 public bool EnableBroadcast {
824 if (disposed && closed) {
825 throw new ObjectDisposedException (GetType ().ToString ());
828 if (protocol_type != ProtocolType.Udp) {
829 throw new SocketException ((int)SocketError.ProtocolOption);
832 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
835 if (disposed && closed) {
836 throw new ObjectDisposedException (GetType ().ToString ());
839 if (protocol_type != ProtocolType.Udp) {
840 throw new SocketException ((int)SocketError.ProtocolOption);
843 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
847 public bool ExclusiveAddressUse {
849 if (disposed && closed) {
850 throw new ObjectDisposedException (GetType ().ToString ());
853 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
856 if (disposed && closed) {
857 throw new ObjectDisposedException (GetType ().ToString ());
860 throw new InvalidOperationException ("Bind has already been called for this socket");
863 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
867 public bool IsBound {
873 public LingerOption LingerState {
875 if (disposed && closed) {
876 throw new ObjectDisposedException (GetType ().ToString ());
879 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
882 if (disposed && closed) {
883 throw new ObjectDisposedException (GetType ().ToString ());
886 SetSocketOption (SocketOptionLevel.Socket,
887 SocketOptionName.Linger,
892 public bool MulticastLoopback {
894 if (disposed && closed) {
895 throw new ObjectDisposedException (GetType ().ToString ());
898 /* Even though this option can be set
899 * for TCP sockets on Linux, throw
900 * this exception anyway to be
901 * compatible (the MSDN docs say
902 * "Setting this property on a
903 * Transmission Control Protocol (TCP)
904 * socket will have no effect." but
905 * the MS runtime throws the
908 if (protocol_type == ProtocolType.Tcp) {
909 throw new SocketException ((int)SocketError.ProtocolOption);
912 bool multicastloopback;
914 if (address_family == AddressFamily.InterNetwork) {
915 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
916 } else if (address_family == AddressFamily.InterNetworkV6) {
917 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
919 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
922 return(multicastloopback);
925 if (disposed && closed) {
926 throw new ObjectDisposedException (GetType ().ToString ());
929 /* Even though this option can be set
930 * for TCP sockets on Linux, throw
931 * this exception anyway to be
932 * compatible (the MSDN docs say
933 * "Setting this property on a
934 * Transmission Control Protocol (TCP)
935 * socket will have no effect." but
936 * the MS runtime throws the
939 if (protocol_type == ProtocolType.Tcp) {
940 throw new SocketException ((int)SocketError.ProtocolOption);
943 if (address_family == AddressFamily.InterNetwork) {
944 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
945 } else if (address_family == AddressFamily.InterNetworkV6) {
946 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
948 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
954 [MonoTODO ("This doesn't do anything on Mono yet")]
955 public bool UseOnlyOverlappedIO {
957 return(useoverlappedIO);
960 useoverlappedIO = value;
965 public IntPtr Handle {
972 // Returns the local endpoint details in addr and port
973 [MethodImplAttribute(MethodImplOptions.InternalCall)]
974 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
977 // Wish: support non-IP endpoints.
978 public EndPoint LocalEndPoint {
980 if (disposed && closed)
981 throw new ObjectDisposedException (GetType ().ToString ());
984 * If the seed EndPoint is null, Connect, Bind,
985 * etc has not yet been called. MS returns null
988 if (seed_endpoint == null)
994 sa=LocalEndPoint_internal(socket, out error);
997 throw new SocketException (error);
999 return seed_endpoint.Create (sa);
1003 public SocketType SocketType {
1005 return(socket_type);
1010 public int SendTimeout {
1012 if (disposed && closed)
1013 throw new ObjectDisposedException (GetType ().ToString ());
1015 return (int)GetSocketOption(
1016 SocketOptionLevel.Socket,
1017 SocketOptionName.SendTimeout);
1020 if (disposed && closed)
1021 throw new ObjectDisposedException (GetType ().ToString ());
1024 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1026 /* According to the MSDN docs we
1027 * should adjust values between 1 and
1028 * 499 to 500, but the MS runtime
1035 SocketOptionLevel.Socket,
1036 SocketOptionName.SendTimeout, value);
1040 public int ReceiveTimeout {
1042 if (disposed && closed)
1043 throw new ObjectDisposedException (GetType ().ToString ());
1045 return (int)GetSocketOption(
1046 SocketOptionLevel.Socket,
1047 SocketOptionName.ReceiveTimeout);
1050 if (disposed && closed)
1051 throw new ObjectDisposedException (GetType ().ToString ());
1054 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1061 SocketOptionLevel.Socket,
1062 SocketOptionName.ReceiveTimeout, value);
1066 public bool AcceptAsync (SocketAsyncEventArgs e)
1068 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1070 if (disposed && closed)
1071 throw new ObjectDisposedException (GetType ().ToString ());
1073 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
1075 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
1076 if (e.BufferList != null)
1077 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1079 throw new ArgumentOutOfRangeException ("e.Count");
1081 Socket acceptSocket = e.AcceptSocket;
1082 if (acceptSocket != null) {
1083 if (acceptSocket.IsBound || acceptSocket.Connected)
1084 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
1086 e.AcceptSocket = new Socket (AddressFamily, SocketType, ProtocolType);
1089 e.DoOperation (SocketAsyncOperation.Accept, this);
1091 ((IDisposable)e).Dispose ();
1095 // We always return true for now
1100 // Creates a new system socket, returning the handle
1101 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1102 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
1104 public Socket Accept() {
1105 if (disposed && closed)
1106 throw new ObjectDisposedException (GetType ().ToString ());
1109 IntPtr sock = (IntPtr) (-1);
1110 blocking_thread = Thread.CurrentThread;
1112 sock = Accept_internal(socket, out error, blocking);
1113 } catch (ThreadAbortException) {
1116 Thread.ResetAbort ();
1118 error = (int) SocketError.Interrupted;
1121 blocking_thread = null;
1125 throw new SocketException (error);
1127 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
1128 this.ProtocolType, sock);
1130 accepted.seed_endpoint = this.seed_endpoint;
1131 accepted.Blocking = this.Blocking;
1135 internal void Accept (Socket acceptSocket)
1137 if (disposed && closed)
1138 throw new ObjectDisposedException (GetType ().ToString ());
1141 IntPtr sock = (IntPtr)(-1);
1142 blocking_thread = Thread.CurrentThread;
1145 sock = Accept_internal (socket, out error, blocking);
1146 } catch (ThreadAbortException) {
1149 Thread.ResetAbort ();
1151 error = (int)SocketError.Interrupted;
1154 blocking_thread = null;
1158 throw new SocketException (error);
1160 acceptSocket.address_family = this.AddressFamily;
1161 acceptSocket.socket_type = this.SocketType;
1162 acceptSocket.protocol_type = this.ProtocolType;
1163 acceptSocket.socket = sock;
1164 acceptSocket.connected = true;
1165 acceptSocket.seed_endpoint = this.seed_endpoint;
1166 acceptSocket.Blocking = this.Blocking;
1168 /* FIXME: figure out what if anything else
1173 public IAsyncResult BeginAccept(AsyncCallback callback,
1176 if (disposed && closed)
1177 throw new ObjectDisposedException (GetType ().ToString ());
1180 /* FIXME: check the 1.1 docs for this too */
1181 if (!isbound || !islistening)
1182 throw new InvalidOperationException ();
1185 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1186 Worker worker = new Worker (req);
1187 SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1188 sac.BeginInvoke (null, req);
1193 public IAsyncResult BeginAccept (int receiveSize,
1194 AsyncCallback callback,
1197 if (disposed && closed)
1198 throw new ObjectDisposedException (GetType ().ToString ());
1200 if (receiveSize < 0)
1201 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1203 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1204 Worker worker = new Worker (req);
1205 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1207 req.Buffer = new byte[receiveSize];
1209 req.Size = receiveSize;
1210 req.SockFlags = SocketFlags.None;
1212 sac.BeginInvoke (null, req);
1216 public IAsyncResult BeginAccept (Socket acceptSocket,
1218 AsyncCallback callback,
1221 if (disposed && closed)
1222 throw new ObjectDisposedException (GetType ().ToString ());
1224 if (receiveSize < 0)
1225 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1227 if (acceptSocket != null) {
1228 if (acceptSocket.disposed && acceptSocket.closed)
1229 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
1231 if (acceptSocket.IsBound)
1232 throw new InvalidOperationException ();
1234 /* For some reason the MS runtime
1235 * barfs if the new socket is not TCP,
1236 * even though it's just about to blow
1237 * away all those parameters
1239 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
1240 throw new SocketException ((int)SocketError.InvalidArgument);
1243 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1244 Worker worker = new Worker (req);
1245 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1247 req.Buffer = new byte[receiveSize];
1249 req.Size = receiveSize;
1250 req.SockFlags = SocketFlags.None;
1251 req.AcceptSocket = acceptSocket;
1253 sac.BeginInvoke (null, req);
1258 public IAsyncResult BeginConnect(EndPoint end_point,
1259 AsyncCallback callback,
1262 if (disposed && closed)
1263 throw new ObjectDisposedException (GetType ().ToString ());
1265 if (end_point == null)
1266 throw new ArgumentNullException ("end_point");
1268 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1269 req.EndPoint = end_point;
1271 // Bug #75154: Connect() should not succeed for .Any addresses.
1272 if (end_point is IPEndPoint) {
1273 IPEndPoint ep = (IPEndPoint) end_point;
1274 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
1275 req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
1282 SocketAddress serial = end_point.Serialize ();
1283 Connect_internal (socket, serial, out error);
1287 req.Complete (true);
1288 } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
1291 req.Complete (new SocketException (error), true);
1295 if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
1298 Worker worker = new Worker (req);
1299 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1300 sac.BeginInvoke (null, req);
1307 public IAsyncResult BeginConnect (IPAddress address, int port,
1308 AsyncCallback callback,
1311 if (disposed && closed)
1312 throw new ObjectDisposedException (GetType ().ToString ());
1314 if (address == null)
1315 throw new ArgumentNullException ("address");
1317 if (address.ToString ().Length == 0)
1318 throw new ArgumentException ("The length of the IP address is zero");
1321 throw new InvalidOperationException ();
1323 IPEndPoint iep = new IPEndPoint (address, port);
1324 return(BeginConnect (iep, callback, state));
1327 public IAsyncResult BeginConnect (IPAddress[] addresses,
1329 AsyncCallback callback,
1332 if (disposed && closed)
1333 throw new ObjectDisposedException (GetType ().ToString ());
1335 if (addresses == null)
1336 throw new ArgumentNullException ("addresses");
1338 if (this.AddressFamily != AddressFamily.InterNetwork &&
1339 this.AddressFamily != AddressFamily.InterNetworkV6)
1340 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1343 throw new InvalidOperationException ();
1345 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1346 req.Addresses = addresses;
1350 Worker worker = new Worker (req);
1351 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1352 sac.BeginInvoke (null, req);
1357 public IAsyncResult BeginConnect (string host, int port,
1358 AsyncCallback callback,
1361 if (disposed && closed)
1362 throw new ObjectDisposedException (GetType ().ToString ());
1365 throw new ArgumentNullException ("host");
1367 if (address_family != AddressFamily.InterNetwork &&
1368 address_family != AddressFamily.InterNetworkV6)
1369 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
1372 throw new InvalidOperationException ();
1374 IPHostEntry hostent = Dns.GetHostEntry (host);
1375 return (BeginConnect (hostent.AddressList, port, callback, state));
1378 public IAsyncResult BeginDisconnect (bool reuseSocket,
1379 AsyncCallback callback,
1382 if (disposed && closed)
1383 throw new ObjectDisposedException (GetType ().ToString ());
1385 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
1386 req.ReuseSocket = reuseSocket;
1388 Worker worker = new Worker (req);
1389 SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
1390 sac.BeginInvoke (null, req);
1396 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1398 SocketFlags socket_flags,
1399 AsyncCallback callback,
1402 if (disposed && closed)
1403 throw new ObjectDisposedException (GetType ().ToString ());
1406 throw new ArgumentNullException ("buffer");
1408 if (offset < 0 || offset > buffer.Length)
1409 throw new ArgumentOutOfRangeException ("offset");
1411 if (size < 0 || offset + size > buffer.Length)
1412 throw new ArgumentOutOfRangeException ("size");
1414 SocketAsyncResult req;
1416 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1417 req.Buffer = buffer;
1418 req.Offset = offset;
1420 req.SockFlags = socket_flags;
1421 readQ.Enqueue (req);
1422 if (readQ.Count == 1) {
1423 Worker worker = new Worker (req);
1424 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1425 sac.BeginInvoke (null, req);
1432 public IAsyncResult BeginReceive (byte[] buffer, int offset,
1433 int size, SocketFlags flags,
1434 out SocketError error,
1435 AsyncCallback callback,
1438 /* As far as I can tell from the docs and from
1439 * experimentation, a pointer to the
1440 * SocketError parameter is not supposed to be
1441 * saved for the async parts. And as we don't
1442 * set any socket errors in the setup code, we
1443 * just have to set it to Success.
1445 error = SocketError.Success;
1446 return (BeginReceive (buffer, offset, size, flags, callback, state));
1449 [CLSCompliant (false)]
1450 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1451 SocketFlags socketFlags,
1452 AsyncCallback callback,
1455 if (disposed && closed)
1456 throw new ObjectDisposedException (GetType ().ToString ());
1458 if (buffers == null)
1459 throw new ArgumentNullException ("buffers");
1461 SocketAsyncResult req;
1463 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
1464 req.Buffers = buffers;
1465 req.SockFlags = socketFlags;
1466 readQ.Enqueue (req);
1467 if (readQ.Count == 1) {
1468 Worker worker = new Worker (req);
1469 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
1470 sac.BeginInvoke (null, req);
1477 [CLSCompliant (false)]
1478 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1479 SocketFlags socketFlags,
1480 out SocketError errorCode,
1481 AsyncCallback callback,
1484 /* I assume the same SocketError semantics as
1487 errorCode = SocketError.Success;
1488 return (BeginReceive (buffers, socketFlags, callback, state));
1492 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1494 SocketFlags socket_flags,
1495 ref EndPoint remote_end,
1496 AsyncCallback callback,
1498 if (disposed && closed)
1499 throw new ObjectDisposedException (GetType ().ToString ());
1502 throw new ArgumentNullException ("buffer");
1505 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1508 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1510 if (offset + size > buffer.Length)
1511 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1513 SocketAsyncResult req;
1515 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1516 req.Buffer = buffer;
1517 req.Offset = offset;
1519 req.SockFlags = socket_flags;
1520 req.EndPoint = remote_end;
1521 readQ.Enqueue (req);
1522 if (readQ.Count == 1) {
1523 Worker worker = new Worker (req);
1524 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1525 sac.BeginInvoke (null, req);
1533 public IAsyncResult BeginReceiveMessageFrom (
1534 byte[] buffer, int offset, int size,
1535 SocketFlags socketFlags, ref EndPoint remoteEP,
1536 AsyncCallback callback, object state)
1538 if (disposed && closed)
1539 throw new ObjectDisposedException (GetType ().ToString ());
1542 throw new ArgumentNullException ("buffer");
1544 if (remoteEP == null)
1545 throw new ArgumentNullException ("remoteEP");
1547 if (offset < 0 || offset > buffer.Length)
1548 throw new ArgumentOutOfRangeException ("offset");
1550 if (size < 0 || offset + size > buffer.Length)
1551 throw new ArgumentOutOfRangeException ("size");
1553 throw new NotImplementedException ();
1557 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1558 AsyncCallback callback, object state)
1560 if (disposed && closed)
1561 throw new ObjectDisposedException (GetType ().ToString ());
1564 throw new ArgumentNullException ("buffer");
1567 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1570 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1572 if (offset + size > buffer.Length)
1573 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1576 /* TODO: Check this exception in the 1.1 profile */
1578 throw new SocketException ((int)SocketError.NotConnected);
1581 SocketAsyncResult req;
1583 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1584 req.Buffer = buffer;
1585 req.Offset = offset;
1587 req.SockFlags = socket_flags;
1588 writeQ.Enqueue (req);
1589 if (writeQ.Count == 1) {
1590 Worker worker = new Worker (req);
1591 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1592 sac.BeginInvoke (null, req);
1599 public IAsyncResult BeginSend (byte[] buffer, int offset,
1601 SocketFlags socketFlags,
1602 out SocketError errorCode,
1603 AsyncCallback callback,
1607 errorCode = SocketError.NotConnected;
1608 throw new SocketException ((int)errorCode);
1611 errorCode = SocketError.Success;
1613 return (BeginSend (buffer, offset, size, socketFlags, callback,
1617 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1618 SocketFlags socketFlags,
1619 AsyncCallback callback,
1622 if (disposed && closed)
1623 throw new ObjectDisposedException (GetType ().ToString ());
1625 if (buffers == null)
1626 throw new ArgumentNullException ("buffers");
1629 throw new SocketException ((int)SocketError.NotConnected);
1631 SocketAsyncResult req;
1633 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
1634 req.Buffers = buffers;
1635 req.SockFlags = socketFlags;
1636 writeQ.Enqueue (req);
1637 if (writeQ.Count == 1) {
1638 Worker worker = new Worker (req);
1639 SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
1640 sac.BeginInvoke (null, req);
1647 [CLSCompliant (false)]
1648 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1649 SocketFlags socketFlags,
1650 out SocketError errorCode,
1651 AsyncCallback callback,
1655 errorCode = SocketError.NotConnected;
1656 throw new SocketException ((int)errorCode);
1659 errorCode = SocketError.Success;
1660 return (BeginSend (buffers, socketFlags, callback, state));
1663 [MonoTODO ("Not implemented")]
1664 public IAsyncResult BeginSendFile (string fileName,
1665 AsyncCallback callback,
1668 if (disposed && closed)
1669 throw new ObjectDisposedException (GetType ().ToString ());
1672 throw new NotSupportedException ();
1674 if (!File.Exists (fileName))
1675 throw new FileNotFoundException ();
1677 throw new NotImplementedException ();
1680 [MonoTODO ("Not implemented")]
1681 public IAsyncResult BeginSendFile (string fileName,
1684 TransmitFileOptions flags,
1685 AsyncCallback callback,
1688 if (disposed && closed)
1689 throw new ObjectDisposedException (GetType ().ToString ());
1692 throw new NotSupportedException ();
1694 if (!File.Exists (fileName))
1695 throw new FileNotFoundException ();
1697 throw new NotImplementedException ();
1701 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1703 SocketFlags socket_flags,
1704 EndPoint remote_end,
1705 AsyncCallback callback,
1707 if (disposed && closed)
1708 throw new ObjectDisposedException (GetType ().ToString ());
1711 throw new ArgumentNullException ("buffer");
1714 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1717 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1719 if (offset + size > buffer.Length)
1720 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1722 SocketAsyncResult req;
1724 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1725 req.Buffer = buffer;
1726 req.Offset = offset;
1728 req.SockFlags = socket_flags;
1729 req.EndPoint = remote_end;
1730 writeQ.Enqueue (req);
1731 if (writeQ.Count == 1) {
1732 Worker worker = new Worker (req);
1733 SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1734 sac.BeginInvoke (null, req);
1740 // Creates a new system socket, returning the handle
1741 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1742 private extern static void Bind_internal(IntPtr sock,
1746 public void Bind(EndPoint local_end) {
1747 if (disposed && closed)
1748 throw new ObjectDisposedException (GetType ().ToString ());
1750 if (local_end == null)
1751 throw new ArgumentNullException("local_end");
1755 Bind_internal(socket, local_end.Serialize(), out error);
1757 throw new SocketException (error);
1763 seed_endpoint = local_end;
1766 #if NET_2_0 && !NET_2_1
1767 public void Close (int timeout)
1769 System.Timers.Timer close_timer = new System.Timers.Timer ();
1770 close_timer.Elapsed += new ElapsedEventHandler (OnTimeoutClose);
1771 close_timer.Interval = timeout * 1000;
1772 close_timer.AutoReset = false;
1773 close_timer.Enabled = true;
1776 private void OnTimeoutClose (object source, ElapsedEventArgs e)
1781 public bool ConnectAsync (SocketAsyncEventArgs e)
1783 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1785 if (disposed && closed)
1786 throw new ObjectDisposedException (GetType ().ToString ());
1788 throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
1789 if (e.RemoteEndPoint == null)
1790 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1791 if (e.BufferList != null)
1792 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1794 e.DoOperation (SocketAsyncOperation.Connect, this);
1796 // We always return true for now
1802 public void Connect (IPAddress address, int port)
1804 Connect (new IPEndPoint (address, port));
1807 public void Connect (IPAddress[] addresses, int port)
1809 if (disposed && closed)
1810 throw new ObjectDisposedException (GetType ().ToString ());
1812 if (addresses == null)
1813 throw new ArgumentNullException ("addresses");
1815 if (this.AddressFamily != AddressFamily.InterNetwork &&
1816 this.AddressFamily != AddressFamily.InterNetworkV6)
1817 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1820 throw new InvalidOperationException ();
1822 /* FIXME: do non-blocking sockets Poll here? */
1823 foreach (IPAddress address in addresses) {
1824 IPEndPoint iep = new IPEndPoint (address,
1826 SocketAddress serial = iep.Serialize ();
1829 Connect_internal (socket, serial, out error);
1832 seed_endpoint = iep;
1834 } else if (error != (int)SocketError.InProgress &&
1835 error != (int)SocketError.WouldBlock) {
1840 Poll (-1, SelectMode.SelectWrite);
1841 int success = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1844 seed_endpoint = iep;
1851 public void Connect (string host, int port)
1853 IPHostEntry hostent = Dns.GetHostEntry (host);
1854 Connect (hostent.AddressList, port);
1858 public bool DisconnectAsync (SocketAsyncEventArgs e)
1860 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1861 if (disposed && closed)
1862 throw new ObjectDisposedException (GetType ().ToString ());
1864 e.DoOperation (SocketAsyncOperation.Disconnect, this);
1869 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1870 private extern static void Disconnect_internal(IntPtr sock,
1874 /* According to the docs, the MS runtime will throw
1875 * PlatformNotSupportedException if the platform is
1876 * newer than w2k. We should be able to cope...
1878 public void Disconnect (bool reuseSocket)
1880 if (disposed && closed)
1881 throw new ObjectDisposedException (GetType ().ToString ());
1885 Disconnect_internal (socket, reuseSocket, out error);
1889 /* ERROR_NOT_SUPPORTED */
1890 throw new PlatformNotSupportedException ();
1892 throw new SocketException (error);
1899 /* Do managed housekeeping here... */
1903 [MonoTODO ("Not implemented")]
1904 public SocketInformation DuplicateAndClose (int targetProcessId)
1906 /* Need to serialize this socket into a
1907 * SocketInformation struct, but must study
1908 * the MS implementation harder to figure out
1909 * behaviour as documentation is lacking
1911 throw new NotImplementedException ();
1915 public Socket EndAccept (IAsyncResult result)
1920 return(EndAccept (out buffer, out bytes, result));
1924 public Socket EndAccept (out byte[] buffer,
1925 IAsyncResult asyncResult)
1929 return(EndAccept (out buffer, out bytes, asyncResult));
1938 Socket EndAccept (out byte[] buffer, out int bytesTransferred,
1939 IAsyncResult asyncResult)
1941 if (disposed && closed)
1942 throw new ObjectDisposedException (GetType ().ToString ());
1944 if (asyncResult == null)
1945 throw new ArgumentNullException ("asyncResult");
1947 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1949 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1951 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1952 throw InvalidAsyncOp ("EndAccept");
1953 if (!asyncResult.IsCompleted)
1954 asyncResult.AsyncWaitHandle.WaitOne ();
1956 req.CheckIfThrowDelayedException ();
1958 buffer = req.Buffer;
1959 bytesTransferred = req.Total;
1964 public void EndConnect (IAsyncResult result)
1966 if (disposed && closed)
1967 throw new ObjectDisposedException (GetType ().ToString ());
1970 throw new ArgumentNullException ("result");
1972 SocketAsyncResult req = result as SocketAsyncResult;
1974 throw new ArgumentException ("Invalid IAsyncResult", "result");
1976 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1977 throw InvalidAsyncOp ("EndConnect");
1978 if (!result.IsCompleted)
1979 result.AsyncWaitHandle.WaitOne();
1981 req.CheckIfThrowDelayedException();
1985 public void EndDisconnect (IAsyncResult asyncResult)
1987 if (disposed && closed)
1988 throw new ObjectDisposedException (GetType ().ToString ());
1990 if (asyncResult == null)
1991 throw new ArgumentNullException ("asyncResult");
1993 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1995 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1997 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1998 throw InvalidAsyncOp ("EndDisconnect");
1999 if (!asyncResult.IsCompleted)
2000 asyncResult.AsyncWaitHandle.WaitOne ();
2002 req.CheckIfThrowDelayedException ();
2006 public int EndReceive (IAsyncResult result)
2010 return (EndReceive (result, out error));
2018 int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2020 if (disposed && closed)
2021 throw new ObjectDisposedException (GetType ().ToString ());
2023 if (asyncResult == null)
2024 throw new ArgumentNullException ("asyncResult");
2026 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2028 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2030 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2031 throw InvalidAsyncOp ("EndReceive");
2032 if (!asyncResult.IsCompleted)
2033 asyncResult.AsyncWaitHandle.WaitOne ();
2035 errorCode = req.ErrorCode;
2036 req.CheckIfThrowDelayedException ();
2041 public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
2043 if (disposed && closed)
2044 throw new ObjectDisposedException (GetType ().ToString ());
2047 throw new ArgumentNullException ("result");
2049 SocketAsyncResult req = result as SocketAsyncResult;
2051 throw new ArgumentException ("Invalid IAsyncResult", "result");
2053 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2054 throw InvalidAsyncOp ("EndReceiveFrom");
2055 if (!result.IsCompleted)
2056 result.AsyncWaitHandle.WaitOne();
2058 req.CheckIfThrowDelayedException();
2059 end_point = req.EndPoint;
2065 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
2066 ref SocketFlags socketFlags,
2067 ref EndPoint endPoint,
2068 out IPPacketInformation ipPacketInformation)
2070 if (disposed && closed)
2071 throw new ObjectDisposedException (GetType ().ToString ());
2073 if (asyncResult == null)
2074 throw new ArgumentNullException ("asyncResult");
2076 if (endPoint == null)
2077 throw new ArgumentNullException ("endPoint");
2079 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2081 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2083 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2084 throw InvalidAsyncOp ("EndReceiveMessageFrom");
2085 throw new NotImplementedException ();
2089 public int EndSend (IAsyncResult result)
2093 return(EndSend (result, out error));
2101 int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2103 if (disposed && closed)
2104 throw new ObjectDisposedException (GetType ().ToString ());
2106 if (asyncResult == null)
2107 throw new ArgumentNullException ("asyncResult");
2109 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2111 throw new ArgumentException ("Invalid IAsyncResult", "result");
2113 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2114 throw InvalidAsyncOp ("EndSend");
2115 if (!asyncResult.IsCompleted)
2116 asyncResult.AsyncWaitHandle.WaitOne ();
2118 errorCode = req.ErrorCode;
2119 req.CheckIfThrowDelayedException ();
2126 public void EndSendFile (IAsyncResult asyncResult)
2128 if (disposed && closed)
2129 throw new ObjectDisposedException (GetType ().ToString ());
2131 if (asyncResult == null)
2132 throw new ArgumentNullException ("asyncResult");
2134 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2136 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2138 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2139 throw InvalidAsyncOp ("EndSendFile");
2140 throw new NotImplementedException ();
2144 Exception InvalidAsyncOp (string method)
2146 return new InvalidOperationException (method + " can only be called once per asynchronous operation");
2149 public int EndSendTo (IAsyncResult result)
2151 if (disposed && closed)
2152 throw new ObjectDisposedException (GetType ().ToString ());
2155 throw new ArgumentNullException ("result");
2157 SocketAsyncResult req = result as SocketAsyncResult;
2159 throw new ArgumentException ("Invalid IAsyncResult", "result");
2161 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2162 throw InvalidAsyncOp ("EndSendTo");
2163 if (!result.IsCompleted)
2164 result.AsyncWaitHandle.WaitOne();
2166 req.CheckIfThrowDelayedException();
2170 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2171 private extern static void GetSocketOption_arr_internal(IntPtr socket,
2172 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
2175 public void GetSocketOption (SocketOptionLevel level, SocketOptionName name, byte [] opt_value)
2177 if (disposed && closed)
2178 throw new ObjectDisposedException (GetType ().ToString ());
2182 GetSocketOption_arr_internal(socket, level, name, ref opt_value,
2185 throw new SocketException (error);
2188 public byte [] GetSocketOption (SocketOptionLevel level, SocketOptionName name, int length)
2190 if (disposed && closed)
2191 throw new ObjectDisposedException (GetType ().ToString ());
2193 byte[] byte_val=new byte[length];
2196 GetSocketOption_arr_internal(socket, level, name, ref byte_val,
2199 throw new SocketException (error);
2204 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
2205 // common options between UNIX and Winsock are FIONREAD,
2206 // FIONBIO and SIOCATMARK. Anything else will depend on the
2208 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2209 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
2210 byte [] output, out int error);
2212 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
2215 throw new ObjectDisposedException (GetType ().ToString ());
2218 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
2222 throw new SocketException (error);
2225 throw new InvalidOperationException ("Must use Blocking property instead.");
2232 public int IOControl (IOControlCode ioControlCode,
2233 byte[] optionInValue,
2234 byte[] optionOutValue)
2236 /* Probably just needs to mirror the int
2237 * overload, but more investigation needed.
2239 throw new NotImplementedException ();
2243 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2244 private extern static void Listen_internal(IntPtr sock, int backlog,
2247 public void Listen (int backlog)
2249 if (disposed && closed)
2250 throw new ObjectDisposedException (GetType ().ToString ());
2253 /* TODO: check if this should be thrown in the
2257 throw new SocketException ((int)SocketError.InvalidArgument);
2262 Listen_internal(socket, backlog, out error);
2265 throw new SocketException (error);
2272 public bool Poll (int time_us, SelectMode mode)
2274 if (disposed && closed)
2275 throw new ObjectDisposedException (GetType ().ToString ());
2277 if (mode != SelectMode.SelectRead &&
2278 mode != SelectMode.SelectWrite &&
2279 mode != SelectMode.SelectError)
2280 throw new NotSupportedException ("'mode' parameter is not valid.");
2283 bool result = Poll_internal (socket, mode, time_us, out error);
2285 throw new SocketException (error);
2287 if (mode == SelectMode.SelectWrite && result && !connected) {
2288 /* Update the connected state; for
2289 * non-blocking Connect()s this is
2290 * when we can find out that the
2291 * connect succeeded.
2293 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
2301 public int Receive (byte [] buf)
2303 if (disposed && closed)
2304 throw new ObjectDisposedException (GetType ().ToString ());
2307 throw new ArgumentNullException ("buf");
2311 int ret = Receive_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2313 if (error != SocketError.Success)
2314 throw new SocketException ((int) error);
2319 public int Receive (byte [] buf, SocketFlags flags)
2321 if (disposed && closed)
2322 throw new ObjectDisposedException (GetType ().ToString ());
2325 throw new ArgumentNullException ("buf");
2329 int ret = Receive_nochecks (buf, 0, buf.Length, flags, out error);
2331 if (error != SocketError.Success) {
2332 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2333 throw new SocketException ((int) error, "Operation timed out.");
2334 throw new SocketException ((int) error);
2340 public int Receive (byte [] buf, int size, SocketFlags flags)
2342 if (disposed && closed)
2343 throw new ObjectDisposedException (GetType ().ToString ());
2346 throw new ArgumentNullException ("buf");
2348 if (size < 0 || size > buf.Length)
2349 throw new ArgumentOutOfRangeException ("size");
2353 int ret = Receive_nochecks (buf, 0, size, flags, out error);
2355 if (error != SocketError.Success) {
2356 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2357 throw new SocketException ((int) error, "Operation timed out.");
2358 throw new SocketException ((int) error);
2364 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
2366 if (disposed && closed)
2367 throw new ObjectDisposedException (GetType ().ToString ());
2370 throw new ArgumentNullException ("buf");
2372 if (offset < 0 || offset > buf.Length)
2373 throw new ArgumentOutOfRangeException ("offset");
2375 if (size < 0 || offset + size > buf.Length)
2376 throw new ArgumentOutOfRangeException ("size");
2380 int ret = Receive_nochecks (buf, offset, size, flags, out error);
2382 if (error != SocketError.Success) {
2383 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2384 throw new SocketException ((int) error, "Operation timed out.");
2385 throw new SocketException ((int) error);
2392 public int Receive (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2394 if (disposed && closed)
2395 throw new ObjectDisposedException (GetType ().ToString ());
2398 throw new ArgumentNullException ("buf");
2400 if (offset < 0 || offset > buf.Length)
2401 throw new ArgumentOutOfRangeException ("offset");
2403 if (size < 0 || offset + size > buf.Length)
2404 throw new ArgumentOutOfRangeException ("size");
2406 return Receive_nochecks (buf, offset, size, flags, out error);
2409 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2410 private extern static int Receive_internal (IntPtr sock,
2415 public int Receive (IList<ArraySegment<byte>> buffers)
2420 ret = Receive (buffers, SocketFlags.None, out error);
2421 if (error != SocketError.Success) {
2422 throw new SocketException ((int)error);
2428 [CLSCompliant (false)]
2429 public int Receive (IList<ArraySegment<byte>> buffers,
2430 SocketFlags socketFlags)
2435 ret = Receive (buffers, socketFlags, out error);
2436 if (error != SocketError.Success) {
2437 throw new SocketException ((int)error);
2443 [CLSCompliant (false)]
2444 public int Receive (IList<ArraySegment<byte>> buffers,
2445 SocketFlags socketFlags,
2446 out SocketError errorCode)
2448 if (buffers == null ||
2449 buffers.Count == 0) {
2450 throw new ArgumentNullException ("buffers");
2453 if (disposed && closed) {
2454 throw new ObjectDisposedException (GetType ().ToString ());
2457 int numsegments = buffers.Count;
2461 /* Only example I can find of sending a byte
2462 * array reference directly into an internal
2464 * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
2465 * so taking a lead from that...
2467 WSABUF[] bufarray = new WSABUF[numsegments];
2468 GCHandle[] gch = new GCHandle[numsegments];
2470 for(int i = 0; i < numsegments; i++) {
2471 ArraySegment<byte> segment = buffers[i];
2472 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2473 bufarray[i].len = segment.Count;
2474 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2478 ret = Receive_internal (socket, bufarray,
2482 for(int i = 0; i < numsegments; i++) {
2483 if (gch[i].IsAllocated) {
2489 errorCode = (SocketError)nativeError;
2495 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
2497 if (disposed && closed)
2498 throw new ObjectDisposedException (GetType ().ToString ());
2500 // We do not support recv into multiple buffers yet
2501 if (e.BufferList != null)
2502 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
2503 if (e.RemoteEndPoint == null)
2504 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2506 e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
2508 // We always return true for now
2513 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
2515 if (disposed && closed)
2516 throw new ObjectDisposedException (GetType ().ToString ());
2519 throw new ArgumentNullException ("buf");
2521 if (remote_end == null)
2522 throw new ArgumentNullException ("remote_end");
2524 return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
2527 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
2529 if (disposed && closed)
2530 throw new ObjectDisposedException (GetType ().ToString ());
2533 throw new ArgumentNullException ("buf");
2535 if (remote_end == null)
2536 throw new ArgumentNullException ("remote_end");
2538 return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
2541 public int ReceiveFrom (byte [] buf, int size, SocketFlags flags,
2542 ref EndPoint remote_end)
2544 if (disposed && closed)
2545 throw new ObjectDisposedException (GetType ().ToString ());
2548 throw new ArgumentNullException ("buf");
2550 if (remote_end == null)
2551 throw new ArgumentNullException ("remote_end");
2553 if (size < 0 || size > buf.Length)
2554 throw new ArgumentOutOfRangeException ("size");
2556 return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
2559 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2560 private extern static int RecvFrom_internal(IntPtr sock,
2565 ref SocketAddress sockaddr,
2568 public int ReceiveFrom (byte [] buf, int offset, int size, SocketFlags flags,
2569 ref EndPoint remote_end)
2571 if (disposed && closed)
2572 throw new ObjectDisposedException (GetType ().ToString ());
2575 throw new ArgumentNullException ("buf");
2577 if (remote_end == null)
2578 throw new ArgumentNullException ("remote_end");
2580 if (offset < 0 || offset > buf.Length)
2581 throw new ArgumentOutOfRangeException ("offset");
2583 if (size < 0 || offset + size > buf.Length)
2584 throw new ArgumentOutOfRangeException ("size");
2586 return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
2589 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
2590 ref EndPoint remote_end)
2593 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
2596 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
2597 ref EndPoint remote_end, bool throwOnError, out int error)
2599 SocketAddress sockaddr = remote_end.Serialize();
2600 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
2601 SocketError err = (SocketError) error;
2603 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2605 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
2607 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
2608 error = (int) SocketError.TimedOut;
2613 throw new SocketException (error);
2623 // If sockaddr is null then we're a connection
2624 // oriented protocol and should ignore the
2625 // remote_end parameter (see MSDN
2626 // documentation for Socket.ReceiveFrom(...) )
2628 if ( sockaddr != null ) {
2629 // Stupidly, EndPoint.Create() is an
2631 remote_end = remote_end.Create (sockaddr);
2634 seed_endpoint = remote_end;
2640 [MonoTODO ("Not implemented")]
2641 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
2643 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2644 if (disposed && closed)
2645 throw new ObjectDisposedException (GetType ().ToString ());
2647 throw new NotImplementedException ();
2650 [MonoTODO ("Not implemented")]
2651 public int ReceiveMessageFrom (byte[] buffer, int offset,
2653 ref SocketFlags socketFlags,
2654 ref EndPoint remoteEP,
2655 out IPPacketInformation ipPacketInformation)
2657 if (disposed && closed)
2658 throw new ObjectDisposedException (GetType ().ToString ());
2661 throw new ArgumentNullException ("buffer");
2663 if (remoteEP == null)
2664 throw new ArgumentNullException ("remoteEP");
2666 if (offset < 0 || offset > buffer.Length)
2667 throw new ArgumentOutOfRangeException ("offset");
2669 if (size < 0 || offset + size > buffer.Length)
2670 throw new ArgumentOutOfRangeException ("size");
2672 /* FIXME: figure out how we get hold of the
2673 * IPPacketInformation
2675 throw new NotImplementedException ();
2678 [MonoTODO ("Not implemented")]
2679 public bool SendPacketsAsync (SocketAsyncEventArgs e)
2681 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2683 if (disposed && closed)
2684 throw new ObjectDisposedException (GetType ().ToString ());
2686 throw new NotImplementedException ();
2691 public int Send (byte [] buf)
2693 if (disposed && closed)
2694 throw new ObjectDisposedException (GetType ().ToString ());
2697 throw new ArgumentNullException ("buf");
2701 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2703 if (error != SocketError.Success)
2704 throw new SocketException ((int) error);
2709 public int Send (byte [] buf, SocketFlags flags)
2711 if (disposed && closed)
2712 throw new ObjectDisposedException (GetType ().ToString ());
2715 throw new ArgumentNullException ("buf");
2719 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
2721 if (error != SocketError.Success)
2722 throw new SocketException ((int) error);
2727 public int Send (byte [] buf, int size, SocketFlags flags)
2729 if (disposed && closed)
2730 throw new ObjectDisposedException (GetType ().ToString ());
2733 throw new ArgumentNullException ("buf");
2735 if (size < 0 || size > buf.Length)
2736 throw new ArgumentOutOfRangeException ("size");
2740 int ret = Send_nochecks (buf, 0, size, flags, out error);
2742 if (error != SocketError.Success)
2743 throw new SocketException ((int) error);
2748 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
2750 if (disposed && closed)
2751 throw new ObjectDisposedException (GetType ().ToString ());
2754 throw new ArgumentNullException ("buffer");
2756 if (offset < 0 || offset > buf.Length)
2757 throw new ArgumentOutOfRangeException ("offset");
2759 if (size < 0 || offset + size > buf.Length)
2760 throw new ArgumentOutOfRangeException ("size");
2764 int ret = Send_nochecks (buf, offset, size, flags, out error);
2766 if (error != SocketError.Success)
2767 throw new SocketException ((int) error);
2773 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2775 if (disposed && closed)
2776 throw new ObjectDisposedException (GetType ().ToString ());
2779 throw new ArgumentNullException ("buffer");
2781 if (offset < 0 || offset > buf.Length)
2782 throw new ArgumentOutOfRangeException ("offset");
2784 if (size < 0 || offset + size > buf.Length)
2785 throw new ArgumentOutOfRangeException ("size");
2787 return Send_nochecks (buf, offset, size, flags, out error);
2790 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2791 private extern static int Send_internal (IntPtr sock,
2796 public int Send (IList<ArraySegment<byte>> buffers)
2801 ret = Send (buffers, SocketFlags.None, out error);
2802 if (error != SocketError.Success) {
2803 throw new SocketException ((int)error);
2809 public int Send (IList<ArraySegment<byte>> buffers,
2810 SocketFlags socketFlags)
2815 ret = Send (buffers, socketFlags, out error);
2816 if (error != SocketError.Success) {
2817 throw new SocketException ((int)error);
2823 [CLSCompliant (false)]
2824 public int Send (IList<ArraySegment<byte>> buffers,
2825 SocketFlags socketFlags,
2826 out SocketError errorCode)
2828 if (disposed && closed) {
2829 throw new ObjectDisposedException (GetType ().ToString ());
2832 if (buffers == null) {
2833 throw new ArgumentNullException ("buffers");
2836 if (buffers.Count == 0) {
2837 throw new ArgumentException ("Buffer is empty", "buffers");
2840 int numsegments = buffers.Count;
2844 WSABUF[] bufarray = new WSABUF[numsegments];
2845 GCHandle[] gch = new GCHandle[numsegments];
2847 for(int i = 0; i < numsegments; i++) {
2848 ArraySegment<byte> segment = buffers[i];
2849 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2850 bufarray[i].len = segment.Count;
2851 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2855 ret = Send_internal (socket, bufarray,
2859 for(int i = 0; i < numsegments; i++) {
2860 if (gch[i].IsAllocated) {
2866 errorCode = (SocketError)nativeError;
2870 [MonoTODO ("Not implemented")]
2871 public void SendFile (string fileName)
2873 if (disposed && closed)
2874 throw new ObjectDisposedException (GetType ().ToString ());
2877 throw new NotSupportedException ();
2880 throw new InvalidOperationException ();
2882 if (!File.Exists (fileName))
2883 throw new FileNotFoundException ();
2885 /* FIXME: Implement TransmitFile */
2886 throw new NotImplementedException ();
2889 [MonoTODO ("Not implemented")]
2890 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
2892 if (disposed && closed)
2893 throw new ObjectDisposedException (GetType ().ToString ());
2896 throw new NotSupportedException ();
2899 throw new InvalidOperationException ();
2901 if (!File.Exists (fileName))
2902 throw new FileNotFoundException ();
2904 /* FIXME: Implement TransmitFile */
2905 throw new NotImplementedException ();
2908 public bool SendToAsync (SocketAsyncEventArgs e)
2910 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2912 if (disposed && closed)
2913 throw new ObjectDisposedException (GetType ().ToString ());
2914 if (e.RemoteEndPoint == null)
2915 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2917 e.DoOperation (SocketAsyncOperation.SendTo, this);
2919 // We always return true for now
2924 public int SendTo (byte [] buffer, EndPoint remote_end)
2926 if (disposed && closed)
2927 throw new ObjectDisposedException (GetType ().ToString ());
2930 throw new ArgumentNullException ("buffer");
2932 if (remote_end == null)
2933 throw new ArgumentNullException ("remote_end");
2935 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2938 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2940 if (disposed && closed)
2941 throw new ObjectDisposedException (GetType ().ToString ());
2944 throw new ArgumentNullException ("buffer");
2946 if (remote_end == null)
2947 throw new ArgumentNullException ("remote_end");
2949 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2952 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2954 if (disposed && closed)
2955 throw new ObjectDisposedException (GetType ().ToString ());
2958 throw new ArgumentNullException ("buffer");
2960 if (remote_end == null)
2961 throw new ArgumentNullException ("remote_end");
2963 if (size < 0 || size > buffer.Length)
2964 throw new ArgumentOutOfRangeException ("size");
2966 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2969 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2970 private extern static int SendTo_internal(IntPtr sock,
2978 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2979 EndPoint remote_end)
2981 if (disposed && closed)
2982 throw new ObjectDisposedException (GetType ().ToString ());
2985 throw new ArgumentNullException ("buffer");
2987 if (remote_end == null)
2988 throw new ArgumentNullException("remote_end");
2990 if (offset < 0 || offset > buffer.Length)
2991 throw new ArgumentOutOfRangeException ("offset");
2993 if (size < 0 || offset + size > buffer.Length)
2994 throw new ArgumentOutOfRangeException ("size");
2996 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2999 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
3000 EndPoint remote_end)
3002 SocketAddress sockaddr = remote_end.Serialize ();
3006 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
3008 SocketError err = (SocketError) error;
3010 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
3013 throw new SocketException (error);
3022 seed_endpoint = remote_end;
3027 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
3029 if (disposed && closed)
3030 throw new ObjectDisposedException (GetType ().ToString ());
3034 SetSocketOption_internal(socket, level, name, null,
3035 opt_value, 0, out error);
3038 throw new SocketException (error);
3041 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
3044 if (disposed && closed)
3045 throw new ObjectDisposedException (GetType ().ToString ());
3047 if (opt_value == null)
3048 throw new ArgumentNullException("opt_value");
3051 /* From MS documentation on SetSocketOption: "For an
3052 * option with a Boolean data type, specify a nonzero
3053 * value to enable the option, and a zero value to
3054 * disable the option."
3055 * Booleans are only handled in 2.0
3058 if (opt_value is System.Boolean) {
3060 bool bool_val = (bool) opt_value;
3061 int int_val = (bool_val) ? 1 : 0;
3063 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
3065 throw new ArgumentException ("Use an integer 1 (true) or 0 (false) instead of a boolean.", "opt_value");
3068 SetSocketOption_internal (socket, level, name, opt_value, null, 0, out error);
3072 throw new SocketException (error);
3076 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue)
3078 if (disposed && closed)
3079 throw new ObjectDisposedException (GetType ().ToString ());
3082 int int_val = (optionValue) ? 1 : 0;
3083 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
3085 throw new SocketException (error);
3090 public override int GetHashCode ()
3093 // The socket is not suitable to serve as a hash code,
3094 // because it will change during its lifetime, but
3095 // this is how MS.NET 1.1 implemented this method.
3096 return (int) socket;