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 int error = (int) SocketError.InProgress; // why?
433 foreach(IPAddress address in result.Addresses) {
434 IPEndPoint iep = new IPEndPoint (address, result.Port);
435 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 (error));
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 IPAddress [] addresses = Dns.GetHostAddresses (host);
1375 return (BeginConnect (addresses, 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 IPAddress [] addresses = Dns.GetHostAddresses (host);
1854 Connect (addresses, 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 ());
2180 if (opt_value == null)
2181 throw new SocketException ((int) SocketError.Fault,
2182 "Error trying to dereference an invalid pointer");
2186 GetSocketOption_arr_internal(socket, level, name, ref opt_value,
2189 throw new SocketException (error);
2192 public byte [] GetSocketOption (SocketOptionLevel level, SocketOptionName name, int length)
2194 if (disposed && closed)
2195 throw new ObjectDisposedException (GetType ().ToString ());
2197 byte[] byte_val=new byte[length];
2200 GetSocketOption_arr_internal(socket, level, name, ref byte_val,
2203 throw new SocketException (error);
2208 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
2209 // common options between UNIX and Winsock are FIONREAD,
2210 // FIONBIO and SIOCATMARK. Anything else will depend on the
2212 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2213 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
2214 byte [] output, out int error);
2216 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
2219 throw new ObjectDisposedException (GetType ().ToString ());
2222 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
2226 throw new SocketException (error);
2229 throw new InvalidOperationException ("Must use Blocking property instead.");
2236 public int IOControl (IOControlCode ioControlCode,
2237 byte[] optionInValue,
2238 byte[] optionOutValue)
2240 /* Probably just needs to mirror the int
2241 * overload, but more investigation needed.
2243 throw new NotImplementedException ();
2247 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2248 private extern static void Listen_internal(IntPtr sock, int backlog,
2251 public void Listen (int backlog)
2253 if (disposed && closed)
2254 throw new ObjectDisposedException (GetType ().ToString ());
2257 /* TODO: check if this should be thrown in the
2261 throw new SocketException ((int)SocketError.InvalidArgument);
2266 Listen_internal(socket, backlog, out error);
2269 throw new SocketException (error);
2276 public bool Poll (int time_us, SelectMode mode)
2278 if (disposed && closed)
2279 throw new ObjectDisposedException (GetType ().ToString ());
2281 if (mode != SelectMode.SelectRead &&
2282 mode != SelectMode.SelectWrite &&
2283 mode != SelectMode.SelectError)
2284 throw new NotSupportedException ("'mode' parameter is not valid.");
2287 bool result = Poll_internal (socket, mode, time_us, out error);
2289 throw new SocketException (error);
2291 if (mode == SelectMode.SelectWrite && result && !connected) {
2292 /* Update the connected state; for
2293 * non-blocking Connect()s this is
2294 * when we can find out that the
2295 * connect succeeded.
2297 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
2305 public int Receive (byte [] buf)
2307 if (disposed && closed)
2308 throw new ObjectDisposedException (GetType ().ToString ());
2311 throw new ArgumentNullException ("buf");
2315 int ret = Receive_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2317 if (error != SocketError.Success)
2318 throw new SocketException ((int) error);
2323 public int Receive (byte [] buf, SocketFlags flags)
2325 if (disposed && closed)
2326 throw new ObjectDisposedException (GetType ().ToString ());
2329 throw new ArgumentNullException ("buf");
2333 int ret = Receive_nochecks (buf, 0, buf.Length, flags, out error);
2335 if (error != SocketError.Success) {
2336 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2337 throw new SocketException ((int) error, "Operation timed out.");
2338 throw new SocketException ((int) error);
2344 public int Receive (byte [] buf, int size, SocketFlags flags)
2346 if (disposed && closed)
2347 throw new ObjectDisposedException (GetType ().ToString ());
2350 throw new ArgumentNullException ("buf");
2352 if (size < 0 || size > buf.Length)
2353 throw new ArgumentOutOfRangeException ("size");
2357 int ret = Receive_nochecks (buf, 0, size, flags, out error);
2359 if (error != SocketError.Success) {
2360 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2361 throw new SocketException ((int) error, "Operation timed out.");
2362 throw new SocketException ((int) error);
2368 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
2370 if (disposed && closed)
2371 throw new ObjectDisposedException (GetType ().ToString ());
2374 throw new ArgumentNullException ("buf");
2376 if (offset < 0 || offset > buf.Length)
2377 throw new ArgumentOutOfRangeException ("offset");
2379 if (size < 0 || offset + size > buf.Length)
2380 throw new ArgumentOutOfRangeException ("size");
2384 int ret = Receive_nochecks (buf, offset, size, flags, out error);
2386 if (error != SocketError.Success) {
2387 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2388 throw new SocketException ((int) error, "Operation timed out.");
2389 throw new SocketException ((int) error);
2396 public int Receive (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2398 if (disposed && closed)
2399 throw new ObjectDisposedException (GetType ().ToString ());
2402 throw new ArgumentNullException ("buf");
2404 if (offset < 0 || offset > buf.Length)
2405 throw new ArgumentOutOfRangeException ("offset");
2407 if (size < 0 || offset + size > buf.Length)
2408 throw new ArgumentOutOfRangeException ("size");
2410 return Receive_nochecks (buf, offset, size, flags, out error);
2413 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2414 private extern static int Receive_internal (IntPtr sock,
2419 public int Receive (IList<ArraySegment<byte>> buffers)
2424 ret = Receive (buffers, SocketFlags.None, out error);
2425 if (error != SocketError.Success) {
2426 throw new SocketException ((int)error);
2432 [CLSCompliant (false)]
2433 public int Receive (IList<ArraySegment<byte>> buffers,
2434 SocketFlags socketFlags)
2439 ret = Receive (buffers, socketFlags, out error);
2440 if (error != SocketError.Success) {
2441 throw new SocketException ((int)error);
2447 [CLSCompliant (false)]
2448 public int Receive (IList<ArraySegment<byte>> buffers,
2449 SocketFlags socketFlags,
2450 out SocketError errorCode)
2452 if (buffers == null ||
2453 buffers.Count == 0) {
2454 throw new ArgumentNullException ("buffers");
2457 if (disposed && closed) {
2458 throw new ObjectDisposedException (GetType ().ToString ());
2461 int numsegments = buffers.Count;
2465 /* Only example I can find of sending a byte
2466 * array reference directly into an internal
2468 * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
2469 * so taking a lead from that...
2471 WSABUF[] bufarray = new WSABUF[numsegments];
2472 GCHandle[] gch = new GCHandle[numsegments];
2474 for(int i = 0; i < numsegments; i++) {
2475 ArraySegment<byte> segment = buffers[i];
2476 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2477 bufarray[i].len = segment.Count;
2478 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2482 ret = Receive_internal (socket, bufarray,
2486 for(int i = 0; i < numsegments; i++) {
2487 if (gch[i].IsAllocated) {
2493 errorCode = (SocketError)nativeError;
2499 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
2501 if (disposed && closed)
2502 throw new ObjectDisposedException (GetType ().ToString ());
2504 // We do not support recv into multiple buffers yet
2505 if (e.BufferList != null)
2506 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
2507 if (e.RemoteEndPoint == null)
2508 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2510 e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
2512 // We always return true for now
2517 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
2519 if (disposed && closed)
2520 throw new ObjectDisposedException (GetType ().ToString ());
2523 throw new ArgumentNullException ("buf");
2525 if (remote_end == null)
2526 throw new ArgumentNullException ("remote_end");
2528 return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
2531 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
2533 if (disposed && closed)
2534 throw new ObjectDisposedException (GetType ().ToString ());
2537 throw new ArgumentNullException ("buf");
2539 if (remote_end == null)
2540 throw new ArgumentNullException ("remote_end");
2542 return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
2545 public int ReceiveFrom (byte [] buf, int size, SocketFlags flags,
2546 ref EndPoint remote_end)
2548 if (disposed && closed)
2549 throw new ObjectDisposedException (GetType ().ToString ());
2552 throw new ArgumentNullException ("buf");
2554 if (remote_end == null)
2555 throw new ArgumentNullException ("remote_end");
2557 if (size < 0 || size > buf.Length)
2558 throw new ArgumentOutOfRangeException ("size");
2560 return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
2563 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2564 private extern static int RecvFrom_internal(IntPtr sock,
2569 ref SocketAddress sockaddr,
2572 public int ReceiveFrom (byte [] buf, int offset, int size, SocketFlags flags,
2573 ref EndPoint remote_end)
2575 if (disposed && closed)
2576 throw new ObjectDisposedException (GetType ().ToString ());
2579 throw new ArgumentNullException ("buf");
2581 if (remote_end == null)
2582 throw new ArgumentNullException ("remote_end");
2584 if (offset < 0 || offset > buf.Length)
2585 throw new ArgumentOutOfRangeException ("offset");
2587 if (size < 0 || offset + size > buf.Length)
2588 throw new ArgumentOutOfRangeException ("size");
2590 return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
2593 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
2594 ref EndPoint remote_end)
2597 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
2600 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
2601 ref EndPoint remote_end, bool throwOnError, out int error)
2603 SocketAddress sockaddr = remote_end.Serialize();
2604 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
2605 SocketError err = (SocketError) error;
2607 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2609 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
2611 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
2612 error = (int) SocketError.TimedOut;
2617 throw new SocketException (error);
2627 // If sockaddr is null then we're a connection
2628 // oriented protocol and should ignore the
2629 // remote_end parameter (see MSDN
2630 // documentation for Socket.ReceiveFrom(...) )
2632 if ( sockaddr != null ) {
2633 // Stupidly, EndPoint.Create() is an
2635 remote_end = remote_end.Create (sockaddr);
2638 seed_endpoint = remote_end;
2644 [MonoTODO ("Not implemented")]
2645 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
2647 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2648 if (disposed && closed)
2649 throw new ObjectDisposedException (GetType ().ToString ());
2651 throw new NotImplementedException ();
2654 [MonoTODO ("Not implemented")]
2655 public int ReceiveMessageFrom (byte[] buffer, int offset,
2657 ref SocketFlags socketFlags,
2658 ref EndPoint remoteEP,
2659 out IPPacketInformation ipPacketInformation)
2661 if (disposed && closed)
2662 throw new ObjectDisposedException (GetType ().ToString ());
2665 throw new ArgumentNullException ("buffer");
2667 if (remoteEP == null)
2668 throw new ArgumentNullException ("remoteEP");
2670 if (offset < 0 || offset > buffer.Length)
2671 throw new ArgumentOutOfRangeException ("offset");
2673 if (size < 0 || offset + size > buffer.Length)
2674 throw new ArgumentOutOfRangeException ("size");
2676 /* FIXME: figure out how we get hold of the
2677 * IPPacketInformation
2679 throw new NotImplementedException ();
2682 [MonoTODO ("Not implemented")]
2683 public bool SendPacketsAsync (SocketAsyncEventArgs e)
2685 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2687 if (disposed && closed)
2688 throw new ObjectDisposedException (GetType ().ToString ());
2690 throw new NotImplementedException ();
2695 public int Send (byte [] buf)
2697 if (disposed && closed)
2698 throw new ObjectDisposedException (GetType ().ToString ());
2701 throw new ArgumentNullException ("buf");
2705 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2707 if (error != SocketError.Success)
2708 throw new SocketException ((int) error);
2713 public int Send (byte [] buf, SocketFlags flags)
2715 if (disposed && closed)
2716 throw new ObjectDisposedException (GetType ().ToString ());
2719 throw new ArgumentNullException ("buf");
2723 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
2725 if (error != SocketError.Success)
2726 throw new SocketException ((int) error);
2731 public int Send (byte [] buf, int size, SocketFlags flags)
2733 if (disposed && closed)
2734 throw new ObjectDisposedException (GetType ().ToString ());
2737 throw new ArgumentNullException ("buf");
2739 if (size < 0 || size > buf.Length)
2740 throw new ArgumentOutOfRangeException ("size");
2744 int ret = Send_nochecks (buf, 0, size, flags, out error);
2746 if (error != SocketError.Success)
2747 throw new SocketException ((int) error);
2752 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
2754 if (disposed && closed)
2755 throw new ObjectDisposedException (GetType ().ToString ());
2758 throw new ArgumentNullException ("buffer");
2760 if (offset < 0 || offset > buf.Length)
2761 throw new ArgumentOutOfRangeException ("offset");
2763 if (size < 0 || offset + size > buf.Length)
2764 throw new ArgumentOutOfRangeException ("size");
2768 int ret = Send_nochecks (buf, offset, size, flags, out error);
2770 if (error != SocketError.Success)
2771 throw new SocketException ((int) error);
2777 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2779 if (disposed && closed)
2780 throw new ObjectDisposedException (GetType ().ToString ());
2783 throw new ArgumentNullException ("buffer");
2785 if (offset < 0 || offset > buf.Length)
2786 throw new ArgumentOutOfRangeException ("offset");
2788 if (size < 0 || offset + size > buf.Length)
2789 throw new ArgumentOutOfRangeException ("size");
2791 return Send_nochecks (buf, offset, size, flags, out error);
2794 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2795 private extern static int Send_internal (IntPtr sock,
2800 public int Send (IList<ArraySegment<byte>> buffers)
2805 ret = Send (buffers, SocketFlags.None, out error);
2806 if (error != SocketError.Success) {
2807 throw new SocketException ((int)error);
2813 public int Send (IList<ArraySegment<byte>> buffers,
2814 SocketFlags socketFlags)
2819 ret = Send (buffers, socketFlags, out error);
2820 if (error != SocketError.Success) {
2821 throw new SocketException ((int)error);
2827 [CLSCompliant (false)]
2828 public int Send (IList<ArraySegment<byte>> buffers,
2829 SocketFlags socketFlags,
2830 out SocketError errorCode)
2832 if (disposed && closed) {
2833 throw new ObjectDisposedException (GetType ().ToString ());
2836 if (buffers == null) {
2837 throw new ArgumentNullException ("buffers");
2840 if (buffers.Count == 0) {
2841 throw new ArgumentException ("Buffer is empty", "buffers");
2844 int numsegments = buffers.Count;
2848 WSABUF[] bufarray = new WSABUF[numsegments];
2849 GCHandle[] gch = new GCHandle[numsegments];
2851 for(int i = 0; i < numsegments; i++) {
2852 ArraySegment<byte> segment = buffers[i];
2853 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2854 bufarray[i].len = segment.Count;
2855 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2859 ret = Send_internal (socket, bufarray,
2863 for(int i = 0; i < numsegments; i++) {
2864 if (gch[i].IsAllocated) {
2870 errorCode = (SocketError)nativeError;
2874 [MonoTODO ("Not implemented")]
2875 public void SendFile (string fileName)
2877 if (disposed && closed)
2878 throw new ObjectDisposedException (GetType ().ToString ());
2881 throw new NotSupportedException ();
2884 throw new InvalidOperationException ();
2886 if (!File.Exists (fileName))
2887 throw new FileNotFoundException ();
2889 /* FIXME: Implement TransmitFile */
2890 throw new NotImplementedException ();
2893 [MonoTODO ("Not implemented")]
2894 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
2896 if (disposed && closed)
2897 throw new ObjectDisposedException (GetType ().ToString ());
2900 throw new NotSupportedException ();
2903 throw new InvalidOperationException ();
2905 if (!File.Exists (fileName))
2906 throw new FileNotFoundException ();
2908 /* FIXME: Implement TransmitFile */
2909 throw new NotImplementedException ();
2912 public bool SendToAsync (SocketAsyncEventArgs e)
2914 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2916 if (disposed && closed)
2917 throw new ObjectDisposedException (GetType ().ToString ());
2918 if (e.RemoteEndPoint == null)
2919 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2921 e.DoOperation (SocketAsyncOperation.SendTo, this);
2923 // We always return true for now
2928 public int SendTo (byte [] buffer, EndPoint remote_end)
2930 if (disposed && closed)
2931 throw new ObjectDisposedException (GetType ().ToString ());
2934 throw new ArgumentNullException ("buffer");
2936 if (remote_end == null)
2937 throw new ArgumentNullException ("remote_end");
2939 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2942 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2944 if (disposed && closed)
2945 throw new ObjectDisposedException (GetType ().ToString ());
2948 throw new ArgumentNullException ("buffer");
2950 if (remote_end == null)
2951 throw new ArgumentNullException ("remote_end");
2953 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2956 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2958 if (disposed && closed)
2959 throw new ObjectDisposedException (GetType ().ToString ());
2962 throw new ArgumentNullException ("buffer");
2964 if (remote_end == null)
2965 throw new ArgumentNullException ("remote_end");
2967 if (size < 0 || size > buffer.Length)
2968 throw new ArgumentOutOfRangeException ("size");
2970 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2973 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2974 private extern static int SendTo_internal(IntPtr sock,
2982 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2983 EndPoint remote_end)
2985 if (disposed && closed)
2986 throw new ObjectDisposedException (GetType ().ToString ());
2989 throw new ArgumentNullException ("buffer");
2991 if (remote_end == null)
2992 throw new ArgumentNullException("remote_end");
2994 if (offset < 0 || offset > buffer.Length)
2995 throw new ArgumentOutOfRangeException ("offset");
2997 if (size < 0 || offset + size > buffer.Length)
2998 throw new ArgumentOutOfRangeException ("size");
3000 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
3003 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
3004 EndPoint remote_end)
3006 SocketAddress sockaddr = remote_end.Serialize ();
3010 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
3012 SocketError err = (SocketError) error;
3014 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
3017 throw new SocketException (error);
3026 seed_endpoint = remote_end;
3031 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
3033 if (disposed && closed)
3034 throw new ObjectDisposedException (GetType ().ToString ());
3036 // I'd throw an ArgumentNullException, but this is what MS does.
3037 if (opt_value == null)
3038 throw new SocketException ((int) SocketError.Fault,
3039 "Error trying to dereference an invalid pointer");
3043 SetSocketOption_internal(socket, level, name, null,
3044 opt_value, 0, out error);
3047 if (error == 10022) // WSAEINVAL
3048 throw new ArgumentException ();
3049 throw new SocketException (error);
3053 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
3056 if (disposed && closed)
3057 throw new ObjectDisposedException (GetType ().ToString ());
3059 if (opt_value == null)
3060 throw new ArgumentNullException("optionValue");
3064 if (level == SocketOptionLevel.Socket && name == SocketOptionName.Linger) {
3065 LingerOption linger = opt_value as LingerOption;
3068 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
3070 throw new ArgumentException ("optionValue");
3072 SetSocketOption_internal (socket, level, name, linger, null, 0, out error);
3073 } else if (level == SocketOptionLevel.IP && (name == SocketOptionName.AddMembership || name == SocketOptionName.DropMembership)) {
3074 MulticastOption multicast = opt_value as MulticastOption;
3075 if (multicast == null)
3077 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
3079 throw new ArgumentException ("optionValue");
3081 SetSocketOption_internal (socket, level, name, multicast, null, 0, out error);
3082 } else if (level == SocketOptionLevel.IPv6 && (name == SocketOptionName.AddMembership || name == SocketOptionName.DropMembership)) {
3083 IPv6MulticastOption multicast = opt_value as IPv6MulticastOption;
3084 if (multicast == null)
3086 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
3088 throw new ArgumentException ("optionValue");
3090 SetSocketOption_internal (socket, level, name, multicast, null, 0, out error);
3093 throw new ArgumentException ("Invalid value specified.", "optionValue");
3095 throw new ArgumentException ("optionValue");
3100 if (error == 10022) // WSAEINVAL
3101 throw new ArgumentException ();
3102 throw new SocketException (error);
3107 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue)
3109 if (disposed && closed)
3110 throw new ObjectDisposedException (GetType ().ToString ());
3113 int int_val = (optionValue) ? 1 : 0;
3114 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
3116 if (error == 10022) // WSAEINVAL
3117 throw new ArgumentException ();
3118 throw new SocketException (error);
3124 public override int GetHashCode ()
3127 // The socket is not suitable to serve as a hash code,
3128 // because it will change during its lifetime, but
3129 // this is how MS.NET 1.1 implemented this method.
3130 return (int) socket;