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;
53 namespace System.Net.Sockets
55 public partial class Socket : IDisposable
57 enum SocketOperation {
74 [StructLayout (LayoutKind.Sequential)]
81 [StructLayout (LayoutKind.Sequential)]
82 private sealed class SocketAsyncResult: IAsyncResult
84 /* Same structure in the runtime */
86 Keep this in sync with MonoSocketAsyncResult in
87 metadata/socket-io.h and ProcessAsyncReader
88 in System.Diagnostics/Process.cs.
94 AsyncCallback callback;
95 WaitHandle waithandle;
97 Exception delayedException;
99 public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
100 public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
101 public int Offset; // Receive,ReceiveFrom,Send,SendTo
102 public int Size; // Receive,ReceiveFrom,Send,SendTo
103 public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
104 public Socket AcceptSocket; // AcceptReceive
105 public IPAddress[] Addresses; // Connect
106 public int Port; // Connect
108 public IList<ArraySegment<byte>> Buffers; // Receive, Send
110 public object Buffers; // Reserve this slot in older profiles
112 public bool ReuseSocket; // Disconnect
120 public bool blocking;
122 SocketOperation operation;
124 public int EndCalled;
126 public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
129 this.blocking = sock.blocking;
130 this.handle = sock.socket;
132 this.callback = callback;
133 this.operation = operation;
134 SockFlags = SocketFlags.None;
137 public void CheckIfThrowDelayedException ()
139 if (delayedException != null) {
140 Sock.connected = false;
141 throw delayedException;
145 Sock.connected = false;
146 throw new SocketException (error);
150 void CompleteAllOnDispose (Queue queue)
152 object [] pending = queue.ToArray ();
156 for (int i = 0; i < pending.Length; i++) {
157 SocketAsyncResult ares = (SocketAsyncResult) pending [i];
158 cb = new WaitCallback (ares.CompleteDisposed);
159 ThreadPool.QueueUserWorkItem (cb, null);
161 if (pending.Length == 0)
165 void CompleteDisposed (object unused)
170 public void Complete ()
172 if (operation != SocketOperation.Receive && Sock.disposed)
173 delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
178 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
180 } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
185 SocketAsyncCall sac = null;
186 SocketAsyncResult req = null;
188 queue.Dequeue (); // remove ourselves
189 if (queue.Count > 0) {
190 req = (SocketAsyncResult) queue.Peek ();
191 if (!Sock.disposed) {
192 Worker worker = new Worker (req);
193 sac = GetDelegate (worker, req.operation);
195 CompleteAllOnDispose (queue);
201 sac.BeginInvoke (null, req);
204 if (callback != null)
209 SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
212 case SocketOperation.Receive:
213 return new SocketAsyncCall (worker.Receive);
214 case SocketOperation.ReceiveFrom:
215 return new SocketAsyncCall (worker.ReceiveFrom);
216 case SocketOperation.Send:
217 return new SocketAsyncCall (worker.Send);
218 case SocketOperation.SendTo:
219 return new SocketAsyncCall (worker.SendTo);
221 return null; // never happens
225 public void Complete (bool synch)
227 completed_sync = synch;
231 public void Complete (int total)
237 public void Complete (Exception e, bool synch)
239 completed_sync = synch;
240 delayedException = e;
244 public void Complete (Exception e)
246 delayedException = e;
250 public void Complete (Socket s)
256 public void Complete (Socket s, int total)
263 public object AsyncState {
269 public WaitHandle AsyncWaitHandle {
272 if (waithandle == null)
273 waithandle = new ManualResetEvent (completed);
283 public bool CompletedSynchronously {
285 return(completed_sync);
289 public bool IsCompleted {
296 if (waithandle != null && value) {
297 ((ManualResetEvent) waithandle).Set ();
303 public Socket Socket {
310 get { return total; }
311 set { total = value; }
314 public SocketError ErrorCode
318 SocketException ex = delayedException as SocketException;
321 return(ex.SocketErrorCode);
324 return((SocketError)error);
326 return(SocketError.Success);
331 private sealed class Worker
333 SocketAsyncResult result;
335 public Worker (SocketAsyncResult ares)
340 public void Accept ()
342 Socket acc_socket = null;
344 acc_socket = result.Sock.Accept ();
345 } catch (Exception e) {
350 result.Complete (acc_socket);
353 /* only used in 2.0 profile and newer, but
354 * leave in older profiles to keep interface
355 * to runtime consistent
357 public void AcceptReceive ()
359 Socket acc_socket = null;
362 if (result.AcceptSocket == null) {
363 acc_socket = result.Sock.Accept ();
365 acc_socket = result.AcceptSocket;
366 result.Sock.Accept (acc_socket);
368 } catch (Exception e) {
373 /* It seems the MS runtime
374 * special-cases 0-length requested
375 * receive data. See bug 464201.
378 if (result.Size > 0) {
382 total = acc_socket.Receive_nochecks (result.Buffer,
387 } catch (Exception e) {
393 result.Complete (acc_socket, total);
396 public void Connect ()
398 /* If result.EndPoint is non-null,
399 * this is the standard one-address
400 * connect attempt. Otherwise
401 * Addresses must be non-null and
402 * contain a list of addresses to try
403 * to connect to; the first one to
404 * succeed causes the rest of the list
407 if (result.EndPoint != null) {
409 if (!result.Sock.Blocking) {
411 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
413 result.Sock.connected = true;
415 result.Complete (new SocketException (success));
419 result.Sock.seed_endpoint = result.EndPoint;
420 result.Sock.Connect (result.EndPoint);
421 result.Sock.connected = true;
423 } catch (Exception e) {
429 } else if (result.Addresses != null) {
430 int error = (int) SocketError.InProgress; // why?
431 foreach(IPAddress address in result.Addresses) {
432 IPEndPoint iep = new IPEndPoint (address, result.Port);
433 SocketAddress serial = iep.Serialize ();
435 Socket.Connect_internal (result.Sock.socket, serial, out error);
437 result.Sock.connected = true;
438 result.Sock.seed_endpoint = iep;
441 } else if (error != (int)SocketError.InProgress &&
442 error != (int)SocketError.WouldBlock) {
446 if (!result.Sock.Blocking) {
448 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
450 result.Sock.connected = true;
451 result.Sock.seed_endpoint = iep;
458 result.Complete (new SocketException (error));
460 result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
464 /* Also only used in 2.0 profile and newer */
465 public void Disconnect ()
469 result.Sock.Disconnect (result.ReuseSocket);
470 } catch (Exception e) {
476 result.Complete (new SocketException ((int)SocketError.Fault));
480 public void Receive ()
482 // Actual recv() done in the runtime
486 public void ReceiveFrom ()
490 total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
494 ref result.EndPoint);
495 } catch (Exception e) {
500 result.Complete (total);
503 public void ReceiveGeneric ()
510 total = result.Sock.Receive (result.Buffers, result.SockFlags, out error);
511 } catch (Exception e) {
516 result.Complete (total);
518 result.Complete (new SocketException ((int)SocketError.Fault));
524 void UpdateSendValues (int last_sent)
526 if (result.error == 0) {
527 send_so_far += last_sent;
528 result.Offset += last_sent;
529 result.Size -= last_sent;
535 // Actual send() done in the runtime
536 if (result.error == 0) {
537 UpdateSendValues (result.Total);
538 if (result.Sock.disposed) {
543 if (result.Size > 0) {
544 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
545 sac.BeginInvoke (null, result);
546 return; // Have to finish writing everything. See bug #74475.
548 result.Total = send_so_far;
553 public void SendTo ()
557 total = result.Sock.SendTo_nochecks (result.Buffer,
563 UpdateSendValues (total);
564 if (result.Size > 0) {
565 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
566 sac.BeginInvoke (null, result);
567 return; // Have to finish writing everything. See bug #74475.
569 result.Total = send_so_far;
570 } catch (Exception e) {
578 public void SendGeneric ()
585 total = result.Sock.Send (result.Buffers, result.SockFlags, out error);
586 } catch (Exception e) {
591 result.Complete (total);
593 result.Complete (new SocketException ((int)SocketError.Fault));
599 private Queue readQ = new Queue (2);
600 private Queue writeQ = new Queue (2);
602 delegate void SocketAsyncCall ();
605 private bool islistening;
606 private bool useoverlappedIO;
610 static void AddSockets (ArrayList sockets, IList list, string name)
613 foreach (Socket sock in list) {
614 if (sock == null) // MS throws a NullRef
615 throw new ArgumentNullException ("name", "Contains a null element");
623 [MethodImplAttribute(MethodImplOptions.InternalCall)]
624 private extern static void Select_internal (ref Socket [] sockets,
628 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
630 ArrayList list = new ArrayList ();
631 AddSockets (list, checkRead, "checkRead");
632 AddSockets (list, checkWrite, "checkWrite");
633 AddSockets (list, checkError, "checkError");
635 if (list.Count == 3) {
636 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
637 "All the lists are null or empty.");
642 * The 'sockets' array contains: READ socket 0-n, null,
643 * WRITE socket 0-n, null,
644 * ERROR socket 0-n, null
646 Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
647 Select_internal (ref sockets, microSeconds, out error);
650 throw new SocketException (error);
652 if (sockets == null) {
653 if (checkRead != null)
655 if (checkWrite != null)
657 if (checkError != null)
663 int count = sockets.Length;
664 IList currentList = checkRead;
666 for (int i = 0; i < count; i++) {
668 Socket sock = sockets [i];
669 if (sock == null) { // separator
670 if (currentList != null) {
671 // Remove non-signaled sockets after the current one
672 int to_remove = currentList.Count - currentIdx;
673 for (int k = 0; k < to_remove; k++)
674 currentList.RemoveAt (currentIdx);
676 currentList = (mode == 0) ? checkWrite : checkError;
682 if (mode == 1 && currentList == checkWrite && !sock.connected) {
683 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
684 sock.connected = true;
687 // Remove non-signaled sockets before the current one
688 int max = currentList.Count;
689 while ((cur_sock = (Socket) currentList [currentIdx]) != sock) {
690 currentList.RemoveAt (currentIdx);
696 // private constructor used by Accept, which already
697 // has a socket handle to use
698 private Socket(AddressFamily family, SocketType type,
699 ProtocolType proto, IntPtr sock)
701 address_family=family;
709 private void SocketDefaults ()
713 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
714 address_family == AddressFamily.InterNetworkV6 */) {
715 /* This is the default, but it
716 * probably has nasty side
717 * effects on Linux, as the
718 * socket option is kludged by
719 * turning on or off PMTU
722 this.DontFragment = false;
726 // Microsoft sets these to 8192, but we are going to keep them
727 // both to the OS defaults as these have a big performance impact.
728 // on WebClient performance.
730 //this.ReceiveBufferSize = 8192;
731 //this.SendBufferSize = 8192;
732 } catch (SocketException) {
740 public Socket (SocketInformation socketInformation)
742 throw new NotImplementedException ("SocketInformation not figured out yet");
744 // ifdef to avoid the warnings.
746 //address_family = socketInformation.address_family;
747 //socket_type = socketInformation.socket_type;
748 //protocol_type = socketInformation.protocol_type;
749 address_family = AddressFamily.InterNetwork;
750 socket_type = SocketType.Stream;
751 protocol_type = ProtocolType.IP;
754 socket = Socket_internal (address_family, socket_type, protocol_type, out error);
756 throw new SocketException (error);
764 // Returns the amount of data waiting to be read on socket
765 [MethodImplAttribute(MethodImplOptions.InternalCall)]
766 private extern static int Available_internal(IntPtr socket, out int error);
769 public int Available {
771 if (disposed && closed)
772 throw new ObjectDisposedException (GetType ().ToString ());
776 ret = Available_internal(socket, out error);
779 throw new SocketException (error);
787 public bool DontFragment {
789 if (disposed && closed) {
790 throw new ObjectDisposedException (GetType ().ToString ());
795 if (address_family == AddressFamily.InterNetwork) {
796 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
797 } else if (address_family == AddressFamily.InterNetworkV6) {
798 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
800 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
803 return(dontfragment);
806 if (disposed && closed) {
807 throw new ObjectDisposedException (GetType ().ToString ());
810 if (address_family == AddressFamily.InterNetwork) {
811 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
812 } else if (address_family == AddressFamily.InterNetworkV6) {
813 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
815 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
820 public bool EnableBroadcast {
822 if (disposed && closed) {
823 throw new ObjectDisposedException (GetType ().ToString ());
826 if (protocol_type != ProtocolType.Udp) {
827 throw new SocketException ((int)SocketError.ProtocolOption);
830 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
833 if (disposed && closed) {
834 throw new ObjectDisposedException (GetType ().ToString ());
837 if (protocol_type != ProtocolType.Udp) {
838 throw new SocketException ((int)SocketError.ProtocolOption);
841 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
845 public bool ExclusiveAddressUse {
847 if (disposed && closed) {
848 throw new ObjectDisposedException (GetType ().ToString ());
851 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
854 if (disposed && closed) {
855 throw new ObjectDisposedException (GetType ().ToString ());
858 throw new InvalidOperationException ("Bind has already been called for this socket");
861 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
865 public bool IsBound {
871 public LingerOption LingerState {
873 if (disposed && closed) {
874 throw new ObjectDisposedException (GetType ().ToString ());
877 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
880 if (disposed && closed) {
881 throw new ObjectDisposedException (GetType ().ToString ());
884 SetSocketOption (SocketOptionLevel.Socket,
885 SocketOptionName.Linger,
890 public bool MulticastLoopback {
892 if (disposed && closed) {
893 throw new ObjectDisposedException (GetType ().ToString ());
896 /* Even though this option can be set
897 * for TCP sockets on Linux, throw
898 * this exception anyway to be
899 * compatible (the MSDN docs say
900 * "Setting this property on a
901 * Transmission Control Protocol (TCP)
902 * socket will have no effect." but
903 * the MS runtime throws the
906 if (protocol_type == ProtocolType.Tcp) {
907 throw new SocketException ((int)SocketError.ProtocolOption);
910 bool multicastloopback;
912 if (address_family == AddressFamily.InterNetwork) {
913 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
914 } else if (address_family == AddressFamily.InterNetworkV6) {
915 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
917 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
920 return(multicastloopback);
923 if (disposed && closed) {
924 throw new ObjectDisposedException (GetType ().ToString ());
927 /* Even though this option can be set
928 * for TCP sockets on Linux, throw
929 * this exception anyway to be
930 * compatible (the MSDN docs say
931 * "Setting this property on a
932 * Transmission Control Protocol (TCP)
933 * socket will have no effect." but
934 * the MS runtime throws the
937 if (protocol_type == ProtocolType.Tcp) {
938 throw new SocketException ((int)SocketError.ProtocolOption);
941 if (address_family == AddressFamily.InterNetwork) {
942 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
943 } else if (address_family == AddressFamily.InterNetworkV6) {
944 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
946 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
952 [MonoTODO ("This doesn't do anything on Mono yet")]
953 public bool UseOnlyOverlappedIO {
955 return(useoverlappedIO);
958 useoverlappedIO = value;
963 public IntPtr Handle {
970 // Returns the local endpoint details in addr and port
971 [MethodImplAttribute(MethodImplOptions.InternalCall)]
972 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
975 // Wish: support non-IP endpoints.
976 public EndPoint LocalEndPoint {
978 if (disposed && closed)
979 throw new ObjectDisposedException (GetType ().ToString ());
982 * If the seed EndPoint is null, Connect, Bind,
983 * etc has not yet been called. MS returns null
986 if (seed_endpoint == null)
992 sa=LocalEndPoint_internal(socket, out error);
995 throw new SocketException (error);
997 return seed_endpoint.Create (sa);
1001 public SocketType SocketType {
1003 return(socket_type);
1008 public int SendTimeout {
1010 if (disposed && closed)
1011 throw new ObjectDisposedException (GetType ().ToString ());
1013 return (int)GetSocketOption(
1014 SocketOptionLevel.Socket,
1015 SocketOptionName.SendTimeout);
1018 if (disposed && closed)
1019 throw new ObjectDisposedException (GetType ().ToString ());
1022 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1024 /* According to the MSDN docs we
1025 * should adjust values between 1 and
1026 * 499 to 500, but the MS runtime
1033 SocketOptionLevel.Socket,
1034 SocketOptionName.SendTimeout, value);
1038 public int ReceiveTimeout {
1040 if (disposed && closed)
1041 throw new ObjectDisposedException (GetType ().ToString ());
1043 return (int)GetSocketOption(
1044 SocketOptionLevel.Socket,
1045 SocketOptionName.ReceiveTimeout);
1048 if (disposed && closed)
1049 throw new ObjectDisposedException (GetType ().ToString ());
1052 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1059 SocketOptionLevel.Socket,
1060 SocketOptionName.ReceiveTimeout, value);
1064 public bool AcceptAsync (SocketAsyncEventArgs e)
1066 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1068 if (disposed && closed)
1069 throw new ObjectDisposedException (GetType ().ToString ());
1071 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
1073 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
1074 if (e.BufferList != null)
1075 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1077 throw new ArgumentOutOfRangeException ("e.Count");
1079 Socket acceptSocket = e.AcceptSocket;
1080 if (acceptSocket != null) {
1081 if (acceptSocket.IsBound || acceptSocket.Connected)
1082 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
1084 e.AcceptSocket = new Socket (AddressFamily, SocketType, ProtocolType);
1087 e.DoOperation (SocketAsyncOperation.Accept, this);
1089 ((IDisposable)e).Dispose ();
1093 // We always return true for now
1098 // Creates a new system socket, returning the handle
1099 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1100 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
1102 public Socket Accept() {
1103 if (disposed && closed)
1104 throw new ObjectDisposedException (GetType ().ToString ());
1107 IntPtr sock = (IntPtr) (-1);
1108 blocking_thread = Thread.CurrentThread;
1110 sock = Accept_internal(socket, out error, blocking);
1111 } catch (ThreadAbortException) {
1113 Thread.ResetAbort ();
1114 error = (int) SocketError.Interrupted;
1117 blocking_thread = null;
1121 throw new SocketException (error);
1123 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
1124 this.ProtocolType, sock);
1126 accepted.seed_endpoint = this.seed_endpoint;
1127 accepted.Blocking = this.Blocking;
1131 internal void Accept (Socket acceptSocket)
1133 if (disposed && closed)
1134 throw new ObjectDisposedException (GetType ().ToString ());
1137 IntPtr sock = (IntPtr)(-1);
1138 blocking_thread = Thread.CurrentThread;
1141 sock = Accept_internal (socket, out error, blocking);
1142 } catch (ThreadAbortException) {
1144 Thread.ResetAbort ();
1145 error = (int)SocketError.Interrupted;
1148 blocking_thread = null;
1152 throw new SocketException (error);
1154 acceptSocket.address_family = this.AddressFamily;
1155 acceptSocket.socket_type = this.SocketType;
1156 acceptSocket.protocol_type = this.ProtocolType;
1157 acceptSocket.socket = sock;
1158 acceptSocket.connected = true;
1159 acceptSocket.seed_endpoint = this.seed_endpoint;
1160 acceptSocket.Blocking = this.Blocking;
1162 /* FIXME: figure out what if anything else
1167 public IAsyncResult BeginAccept(AsyncCallback callback,
1170 if (disposed && closed)
1171 throw new ObjectDisposedException (GetType ().ToString ());
1174 /* FIXME: check the 1.1 docs for this too */
1175 if (!isbound || !islistening)
1176 throw new InvalidOperationException ();
1179 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1180 Worker worker = new Worker (req);
1181 SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1182 sac.BeginInvoke (null, req);
1187 public IAsyncResult BeginAccept (int receiveSize,
1188 AsyncCallback callback,
1191 if (disposed && closed)
1192 throw new ObjectDisposedException (GetType ().ToString ());
1194 if (receiveSize < 0)
1195 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1197 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1198 Worker worker = new Worker (req);
1199 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1201 req.Buffer = new byte[receiveSize];
1203 req.Size = receiveSize;
1204 req.SockFlags = SocketFlags.None;
1206 sac.BeginInvoke (null, req);
1210 public IAsyncResult BeginAccept (Socket acceptSocket,
1212 AsyncCallback callback,
1215 if (disposed && closed)
1216 throw new ObjectDisposedException (GetType ().ToString ());
1218 if (receiveSize < 0)
1219 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1221 if (acceptSocket != null) {
1222 if (acceptSocket.disposed && acceptSocket.closed)
1223 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
1225 if (acceptSocket.IsBound)
1226 throw new InvalidOperationException ();
1228 /* For some reason the MS runtime
1229 * barfs if the new socket is not TCP,
1230 * even though it's just about to blow
1231 * away all those parameters
1233 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
1234 throw new SocketException ((int)SocketError.InvalidArgument);
1237 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1238 Worker worker = new Worker (req);
1239 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1241 req.Buffer = new byte[receiveSize];
1243 req.Size = receiveSize;
1244 req.SockFlags = SocketFlags.None;
1245 req.AcceptSocket = acceptSocket;
1247 sac.BeginInvoke (null, req);
1252 public IAsyncResult BeginConnect(EndPoint end_point,
1253 AsyncCallback callback,
1256 if (disposed && closed)
1257 throw new ObjectDisposedException (GetType ().ToString ());
1259 if (end_point == null)
1260 throw new ArgumentNullException ("end_point");
1262 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1263 req.EndPoint = end_point;
1265 // Bug #75154: Connect() should not succeed for .Any addresses.
1266 if (end_point is IPEndPoint) {
1267 IPEndPoint ep = (IPEndPoint) end_point;
1268 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
1269 req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
1276 SocketAddress serial = end_point.Serialize ();
1277 Connect_internal (socket, serial, out error);
1281 req.Complete (true);
1282 } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
1285 req.Complete (new SocketException (error), true);
1289 if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
1292 Worker worker = new Worker (req);
1293 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1294 sac.BeginInvoke (null, req);
1301 public IAsyncResult BeginConnect (IPAddress address, int port,
1302 AsyncCallback callback,
1305 if (disposed && closed)
1306 throw new ObjectDisposedException (GetType ().ToString ());
1308 if (address == null)
1309 throw new ArgumentNullException ("address");
1311 if (address.ToString ().Length == 0)
1312 throw new ArgumentException ("The length of the IP address is zero");
1315 throw new InvalidOperationException ();
1317 IPEndPoint iep = new IPEndPoint (address, port);
1318 return(BeginConnect (iep, callback, state));
1321 public IAsyncResult BeginConnect (IPAddress[] addresses,
1323 AsyncCallback callback,
1326 if (disposed && closed)
1327 throw new ObjectDisposedException (GetType ().ToString ());
1329 if (addresses == null)
1330 throw new ArgumentNullException ("addresses");
1332 if (this.AddressFamily != AddressFamily.InterNetwork &&
1333 this.AddressFamily != AddressFamily.InterNetworkV6)
1334 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1337 throw new InvalidOperationException ();
1339 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1340 req.Addresses = addresses;
1344 Worker worker = new Worker (req);
1345 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1346 sac.BeginInvoke (null, req);
1351 public IAsyncResult BeginConnect (string host, int port,
1352 AsyncCallback callback,
1355 if (disposed && closed)
1356 throw new ObjectDisposedException (GetType ().ToString ());
1359 throw new ArgumentNullException ("host");
1361 if (address_family != AddressFamily.InterNetwork &&
1362 address_family != AddressFamily.InterNetworkV6)
1363 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
1366 throw new InvalidOperationException ();
1368 IPAddress [] addresses = Dns.GetHostAddresses (host);
1369 return (BeginConnect (addresses, port, callback, state));
1372 public IAsyncResult BeginDisconnect (bool reuseSocket,
1373 AsyncCallback callback,
1376 if (disposed && closed)
1377 throw new ObjectDisposedException (GetType ().ToString ());
1379 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
1380 req.ReuseSocket = reuseSocket;
1382 Worker worker = new Worker (req);
1383 SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
1384 sac.BeginInvoke (null, req);
1390 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1392 SocketFlags socket_flags,
1393 AsyncCallback callback,
1396 if (disposed && closed)
1397 throw new ObjectDisposedException (GetType ().ToString ());
1400 throw new ArgumentNullException ("buffer");
1402 if (offset < 0 || offset > buffer.Length)
1403 throw new ArgumentOutOfRangeException ("offset");
1405 if (size < 0 || offset + size > buffer.Length)
1406 throw new ArgumentOutOfRangeException ("size");
1408 SocketAsyncResult req;
1410 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1411 req.Buffer = buffer;
1412 req.Offset = offset;
1414 req.SockFlags = socket_flags;
1415 readQ.Enqueue (req);
1416 if (readQ.Count == 1) {
1417 Worker worker = new Worker (req);
1418 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1419 sac.BeginInvoke (null, req);
1426 public IAsyncResult BeginReceive (byte[] buffer, int offset,
1427 int size, SocketFlags flags,
1428 out SocketError error,
1429 AsyncCallback callback,
1432 /* As far as I can tell from the docs and from
1433 * experimentation, a pointer to the
1434 * SocketError parameter is not supposed to be
1435 * saved for the async parts. And as we don't
1436 * set any socket errors in the setup code, we
1437 * just have to set it to Success.
1439 error = SocketError.Success;
1440 return (BeginReceive (buffer, offset, size, flags, callback, state));
1443 [CLSCompliant (false)]
1444 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1445 SocketFlags socketFlags,
1446 AsyncCallback callback,
1449 if (disposed && closed)
1450 throw new ObjectDisposedException (GetType ().ToString ());
1452 if (buffers == null)
1453 throw new ArgumentNullException ("buffers");
1455 SocketAsyncResult req;
1457 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
1458 req.Buffers = buffers;
1459 req.SockFlags = socketFlags;
1460 readQ.Enqueue (req);
1461 if (readQ.Count == 1) {
1462 Worker worker = new Worker (req);
1463 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
1464 sac.BeginInvoke (null, req);
1471 [CLSCompliant (false)]
1472 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1473 SocketFlags socketFlags,
1474 out SocketError errorCode,
1475 AsyncCallback callback,
1478 /* I assume the same SocketError semantics as
1481 errorCode = SocketError.Success;
1482 return (BeginReceive (buffers, socketFlags, callback, state));
1486 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1488 SocketFlags socket_flags,
1489 ref EndPoint remote_end,
1490 AsyncCallback callback,
1492 if (disposed && closed)
1493 throw new ObjectDisposedException (GetType ().ToString ());
1496 throw new ArgumentNullException ("buffer");
1499 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1502 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1504 if (offset + size > buffer.Length)
1505 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1507 SocketAsyncResult req;
1509 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1510 req.Buffer = buffer;
1511 req.Offset = offset;
1513 req.SockFlags = socket_flags;
1514 req.EndPoint = remote_end;
1515 readQ.Enqueue (req);
1516 if (readQ.Count == 1) {
1517 Worker worker = new Worker (req);
1518 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1519 sac.BeginInvoke (null, req);
1527 public IAsyncResult BeginReceiveMessageFrom (
1528 byte[] buffer, int offset, int size,
1529 SocketFlags socketFlags, ref EndPoint remoteEP,
1530 AsyncCallback callback, object state)
1532 if (disposed && closed)
1533 throw new ObjectDisposedException (GetType ().ToString ());
1536 throw new ArgumentNullException ("buffer");
1538 if (remoteEP == null)
1539 throw new ArgumentNullException ("remoteEP");
1541 if (offset < 0 || offset > buffer.Length)
1542 throw new ArgumentOutOfRangeException ("offset");
1544 if (size < 0 || offset + size > buffer.Length)
1545 throw new ArgumentOutOfRangeException ("size");
1547 throw new NotImplementedException ();
1551 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1552 AsyncCallback callback, object state)
1554 if (disposed && closed)
1555 throw new ObjectDisposedException (GetType ().ToString ());
1558 throw new ArgumentNullException ("buffer");
1561 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1564 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1566 if (offset + size > buffer.Length)
1567 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1570 /* TODO: Check this exception in the 1.1 profile */
1572 throw new SocketException ((int)SocketError.NotConnected);
1575 SocketAsyncResult req;
1577 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1578 req.Buffer = buffer;
1579 req.Offset = offset;
1581 req.SockFlags = socket_flags;
1582 writeQ.Enqueue (req);
1583 if (writeQ.Count == 1) {
1584 Worker worker = new Worker (req);
1585 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1586 sac.BeginInvoke (null, req);
1593 public IAsyncResult BeginSend (byte[] buffer, int offset,
1595 SocketFlags socketFlags,
1596 out SocketError errorCode,
1597 AsyncCallback callback,
1601 errorCode = SocketError.NotConnected;
1602 throw new SocketException ((int)errorCode);
1605 errorCode = SocketError.Success;
1607 return (BeginSend (buffer, offset, size, socketFlags, callback,
1611 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1612 SocketFlags socketFlags,
1613 AsyncCallback callback,
1616 if (disposed && closed)
1617 throw new ObjectDisposedException (GetType ().ToString ());
1619 if (buffers == null)
1620 throw new ArgumentNullException ("buffers");
1623 throw new SocketException ((int)SocketError.NotConnected);
1625 SocketAsyncResult req;
1627 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
1628 req.Buffers = buffers;
1629 req.SockFlags = socketFlags;
1630 writeQ.Enqueue (req);
1631 if (writeQ.Count == 1) {
1632 Worker worker = new Worker (req);
1633 SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
1634 sac.BeginInvoke (null, req);
1641 [CLSCompliant (false)]
1642 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1643 SocketFlags socketFlags,
1644 out SocketError errorCode,
1645 AsyncCallback callback,
1649 errorCode = SocketError.NotConnected;
1650 throw new SocketException ((int)errorCode);
1653 errorCode = SocketError.Success;
1654 return (BeginSend (buffers, socketFlags, callback, state));
1657 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
1659 sealed class SendFileAsyncResult : IAsyncResult {
1663 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
1669 public object AsyncState {
1670 get { return ares.AsyncState; }
1673 public WaitHandle AsyncWaitHandle {
1674 get { return ares.AsyncWaitHandle; }
1677 public bool CompletedSynchronously {
1678 get { return ares.CompletedSynchronously; }
1681 public bool IsCompleted {
1682 get { return ares.IsCompleted; }
1685 public SendFileHandler Delegate {
1689 public IAsyncResult Original {
1690 get { return ares; }
1694 public IAsyncResult BeginSendFile (string fileName,
1695 AsyncCallback callback,
1698 if (disposed && closed)
1699 throw new ObjectDisposedException (GetType ().ToString ());
1702 throw new NotSupportedException ();
1704 if (!File.Exists (fileName))
1705 throw new FileNotFoundException ();
1707 return BeginSendFile (fileName, null, null, 0, callback, state);
1710 public IAsyncResult BeginSendFile (string fileName,
1713 TransmitFileOptions flags,
1714 AsyncCallback callback,
1717 if (disposed && closed)
1718 throw new ObjectDisposedException (GetType ().ToString ());
1721 throw new NotSupportedException ();
1723 if (!File.Exists (fileName))
1724 throw new FileNotFoundException ();
1726 SendFileHandler d = new SendFileHandler (SendFile);
1727 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
1731 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1733 SocketFlags socket_flags,
1734 EndPoint remote_end,
1735 AsyncCallback callback,
1737 if (disposed && closed)
1738 throw new ObjectDisposedException (GetType ().ToString ());
1741 throw new ArgumentNullException ("buffer");
1744 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1747 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1749 if (offset + size > buffer.Length)
1750 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1752 SocketAsyncResult req;
1754 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1755 req.Buffer = buffer;
1756 req.Offset = offset;
1758 req.SockFlags = socket_flags;
1759 req.EndPoint = remote_end;
1760 writeQ.Enqueue (req);
1761 if (writeQ.Count == 1) {
1762 Worker worker = new Worker (req);
1763 SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1764 sac.BeginInvoke (null, req);
1770 // Creates a new system socket, returning the handle
1771 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1772 private extern static void Bind_internal(IntPtr sock,
1776 public void Bind(EndPoint local_end) {
1777 if (disposed && closed)
1778 throw new ObjectDisposedException (GetType ().ToString ());
1780 if (local_end == null)
1781 throw new ArgumentNullException("local_end");
1785 Bind_internal(socket, local_end.Serialize(), out error);
1787 throw new SocketException (error);
1793 seed_endpoint = local_end;
1797 public bool ConnectAsync (SocketAsyncEventArgs e)
1799 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1801 if (disposed && closed)
1802 throw new ObjectDisposedException (GetType ().ToString ());
1804 throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
1805 if (e.RemoteEndPoint == null)
1806 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1807 if (e.BufferList != null)
1808 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1810 e.DoOperation (SocketAsyncOperation.Connect, this);
1812 // We always return true for now
1818 public void Connect (IPAddress address, int port)
1820 Connect (new IPEndPoint (address, port));
1823 public void Connect (IPAddress[] addresses, int port)
1825 if (disposed && closed)
1826 throw new ObjectDisposedException (GetType ().ToString ());
1828 if (addresses == null)
1829 throw new ArgumentNullException ("addresses");
1831 if (this.AddressFamily != AddressFamily.InterNetwork &&
1832 this.AddressFamily != AddressFamily.InterNetworkV6)
1833 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1836 throw new InvalidOperationException ();
1838 /* FIXME: do non-blocking sockets Poll here? */
1839 foreach (IPAddress address in addresses) {
1840 IPEndPoint iep = new IPEndPoint (address,
1842 SocketAddress serial = iep.Serialize ();
1845 Connect_internal (socket, serial, out error);
1848 seed_endpoint = iep;
1850 } else if (error != (int)SocketError.InProgress &&
1851 error != (int)SocketError.WouldBlock) {
1856 Poll (-1, SelectMode.SelectWrite);
1857 int success = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1860 seed_endpoint = iep;
1867 public void Connect (string host, int port)
1869 IPAddress [] addresses = Dns.GetHostAddresses (host);
1870 Connect (addresses, port);
1874 public bool DisconnectAsync (SocketAsyncEventArgs e)
1876 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1877 if (disposed && closed)
1878 throw new ObjectDisposedException (GetType ().ToString ());
1880 e.DoOperation (SocketAsyncOperation.Disconnect, this);
1885 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1886 private extern static void Disconnect_internal(IntPtr sock,
1890 /* According to the docs, the MS runtime will throw
1891 * PlatformNotSupportedException if the platform is
1892 * newer than w2k. We should be able to cope...
1894 public void Disconnect (bool reuseSocket)
1896 if (disposed && closed)
1897 throw new ObjectDisposedException (GetType ().ToString ());
1901 Disconnect_internal (socket, reuseSocket, out error);
1905 /* ERROR_NOT_SUPPORTED */
1906 throw new PlatformNotSupportedException ();
1908 throw new SocketException (error);
1915 /* Do managed housekeeping here... */
1919 [MonoTODO ("Not implemented")]
1920 public SocketInformation DuplicateAndClose (int targetProcessId)
1922 /* Need to serialize this socket into a
1923 * SocketInformation struct, but must study
1924 * the MS implementation harder to figure out
1925 * behaviour as documentation is lacking
1927 throw new NotImplementedException ();
1931 public Socket EndAccept (IAsyncResult result)
1936 return(EndAccept (out buffer, out bytes, result));
1940 public Socket EndAccept (out byte[] buffer,
1941 IAsyncResult asyncResult)
1945 return(EndAccept (out buffer, out bytes, asyncResult));
1954 Socket EndAccept (out byte[] buffer, out int bytesTransferred,
1955 IAsyncResult asyncResult)
1957 if (disposed && closed)
1958 throw new ObjectDisposedException (GetType ().ToString ());
1960 if (asyncResult == null)
1961 throw new ArgumentNullException ("asyncResult");
1963 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1965 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1967 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1968 throw InvalidAsyncOp ("EndAccept");
1969 if (!asyncResult.IsCompleted)
1970 asyncResult.AsyncWaitHandle.WaitOne ();
1972 req.CheckIfThrowDelayedException ();
1974 buffer = req.Buffer;
1975 bytesTransferred = req.Total;
1980 public void EndConnect (IAsyncResult result)
1982 if (disposed && closed)
1983 throw new ObjectDisposedException (GetType ().ToString ());
1986 throw new ArgumentNullException ("result");
1988 SocketAsyncResult req = result as SocketAsyncResult;
1990 throw new ArgumentException ("Invalid IAsyncResult", "result");
1992 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1993 throw InvalidAsyncOp ("EndConnect");
1994 if (!result.IsCompleted)
1995 result.AsyncWaitHandle.WaitOne();
1997 req.CheckIfThrowDelayedException();
2001 public void EndDisconnect (IAsyncResult asyncResult)
2003 if (disposed && closed)
2004 throw new ObjectDisposedException (GetType ().ToString ());
2006 if (asyncResult == null)
2007 throw new ArgumentNullException ("asyncResult");
2009 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2011 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2013 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2014 throw InvalidAsyncOp ("EndDisconnect");
2015 if (!asyncResult.IsCompleted)
2016 asyncResult.AsyncWaitHandle.WaitOne ();
2018 req.CheckIfThrowDelayedException ();
2022 public int EndReceive (IAsyncResult result)
2026 return (EndReceive (result, out error));
2034 int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2036 if (disposed && closed)
2037 throw new ObjectDisposedException (GetType ().ToString ());
2039 if (asyncResult == null)
2040 throw new ArgumentNullException ("asyncResult");
2042 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2044 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2046 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2047 throw InvalidAsyncOp ("EndReceive");
2048 if (!asyncResult.IsCompleted)
2049 asyncResult.AsyncWaitHandle.WaitOne ();
2051 errorCode = req.ErrorCode;
2052 req.CheckIfThrowDelayedException ();
2057 public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
2059 if (disposed && closed)
2060 throw new ObjectDisposedException (GetType ().ToString ());
2063 throw new ArgumentNullException ("result");
2065 SocketAsyncResult req = result as SocketAsyncResult;
2067 throw new ArgumentException ("Invalid IAsyncResult", "result");
2069 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2070 throw InvalidAsyncOp ("EndReceiveFrom");
2071 if (!result.IsCompleted)
2072 result.AsyncWaitHandle.WaitOne();
2074 req.CheckIfThrowDelayedException();
2075 end_point = req.EndPoint;
2081 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
2082 ref SocketFlags socketFlags,
2083 ref EndPoint endPoint,
2084 out IPPacketInformation ipPacketInformation)
2086 if (disposed && closed)
2087 throw new ObjectDisposedException (GetType ().ToString ());
2089 if (asyncResult == null)
2090 throw new ArgumentNullException ("asyncResult");
2092 if (endPoint == null)
2093 throw new ArgumentNullException ("endPoint");
2095 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2097 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2099 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2100 throw InvalidAsyncOp ("EndReceiveMessageFrom");
2101 throw new NotImplementedException ();
2105 public int EndSend (IAsyncResult result)
2109 return(EndSend (result, out error));
2117 int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2119 if (disposed && closed)
2120 throw new ObjectDisposedException (GetType ().ToString ());
2122 if (asyncResult == null)
2123 throw new ArgumentNullException ("asyncResult");
2125 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2127 throw new ArgumentException ("Invalid IAsyncResult", "result");
2129 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2130 throw InvalidAsyncOp ("EndSend");
2131 if (!asyncResult.IsCompleted)
2132 asyncResult.AsyncWaitHandle.WaitOne ();
2134 errorCode = req.ErrorCode;
2135 req.CheckIfThrowDelayedException ();
2141 public void EndSendFile (IAsyncResult asyncResult)
2143 if (disposed && closed)
2144 throw new ObjectDisposedException (GetType ().ToString ());
2146 if (asyncResult == null)
2147 throw new ArgumentNullException ("asyncResult");
2149 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
2151 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2153 ares.Delegate.EndInvoke (ares.Original);
2157 Exception InvalidAsyncOp (string method)
2159 return new InvalidOperationException (method + " can only be called once per asynchronous operation");
2162 public int EndSendTo (IAsyncResult result)
2164 if (disposed && closed)
2165 throw new ObjectDisposedException (GetType ().ToString ());
2168 throw new ArgumentNullException ("result");
2170 SocketAsyncResult req = result as SocketAsyncResult;
2172 throw new ArgumentException ("Invalid IAsyncResult", "result");
2174 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2175 throw InvalidAsyncOp ("EndSendTo");
2176 if (!result.IsCompleted)
2177 result.AsyncWaitHandle.WaitOne();
2179 req.CheckIfThrowDelayedException();
2183 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2184 private extern static void GetSocketOption_arr_internal(IntPtr socket,
2185 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
2188 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2190 if (disposed && closed)
2191 throw new ObjectDisposedException (GetType ().ToString ());
2193 if (optionValue == null)
2194 throw new SocketException ((int) SocketError.Fault,
2195 "Error trying to dereference an invalid pointer");
2199 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
2202 throw new SocketException (error);
2205 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
2207 if (disposed && closed)
2208 throw new ObjectDisposedException (GetType ().ToString ());
2210 byte[] byte_val=new byte[length];
2213 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
2216 throw new SocketException (error);
2221 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
2222 // common options between UNIX and Winsock are FIONREAD,
2223 // FIONBIO and SIOCATMARK. Anything else will depend on the
2225 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2226 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
2227 byte [] output, out int error);
2229 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
2232 throw new ObjectDisposedException (GetType ().ToString ());
2235 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
2239 throw new SocketException (error);
2242 throw new InvalidOperationException ("Must use Blocking property instead.");
2249 public int IOControl (IOControlCode ioControlCode,
2250 byte[] optionInValue,
2251 byte[] optionOutValue)
2253 /* Probably just needs to mirror the int
2254 * overload, but more investigation needed.
2256 throw new NotImplementedException ();
2260 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2261 private extern static void Listen_internal(IntPtr sock, int backlog,
2264 public void Listen (int backlog)
2266 if (disposed && closed)
2267 throw new ObjectDisposedException (GetType ().ToString ());
2270 /* TODO: check if this should be thrown in the
2274 throw new SocketException ((int)SocketError.InvalidArgument);
2279 Listen_internal(socket, backlog, out error);
2282 throw new SocketException (error);
2289 public bool Poll (int time_us, SelectMode mode)
2291 if (disposed && closed)
2292 throw new ObjectDisposedException (GetType ().ToString ());
2294 if (mode != SelectMode.SelectRead &&
2295 mode != SelectMode.SelectWrite &&
2296 mode != SelectMode.SelectError)
2297 throw new NotSupportedException ("'mode' parameter is not valid.");
2300 bool result = Poll_internal (socket, mode, time_us, out error);
2302 throw new SocketException (error);
2304 if (mode == SelectMode.SelectWrite && result && !connected) {
2305 /* Update the connected state; for
2306 * non-blocking Connect()s this is
2307 * when we can find out that the
2308 * connect succeeded.
2310 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
2318 public int Receive (byte [] buffer)
2320 if (disposed && closed)
2321 throw new ObjectDisposedException (GetType ().ToString ());
2324 throw new ArgumentNullException ("buffer");
2328 int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
2330 if (error != SocketError.Success)
2331 throw new SocketException ((int) error);
2336 public int Receive (byte [] buffer, SocketFlags flags)
2338 if (disposed && closed)
2339 throw new ObjectDisposedException (GetType ().ToString ());
2342 throw new ArgumentNullException ("buffer");
2346 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
2348 if (error != SocketError.Success) {
2349 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2350 throw new SocketException ((int) error, "Operation timed out.");
2351 throw new SocketException ((int) error);
2357 public int Receive (byte [] buffer, int size, SocketFlags flags)
2359 if (disposed && closed)
2360 throw new ObjectDisposedException (GetType ().ToString ());
2363 throw new ArgumentNullException ("buffer");
2365 if (size < 0 || size > buffer.Length)
2366 throw new ArgumentOutOfRangeException ("size");
2370 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
2372 if (error != SocketError.Success) {
2373 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2374 throw new SocketException ((int) error, "Operation timed out.");
2375 throw new SocketException ((int) error);
2381 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
2383 if (disposed && closed)
2384 throw new ObjectDisposedException (GetType ().ToString ());
2387 throw new ArgumentNullException ("buffer");
2389 if (offset < 0 || offset > buffer.Length)
2390 throw new ArgumentOutOfRangeException ("offset");
2392 if (size < 0 || offset + size > buffer.Length)
2393 throw new ArgumentOutOfRangeException ("size");
2397 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
2399 if (error != SocketError.Success) {
2400 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2401 throw new SocketException ((int) error, "Operation timed out.");
2402 throw new SocketException ((int) error);
2409 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
2411 if (disposed && closed)
2412 throw new ObjectDisposedException (GetType ().ToString ());
2415 throw new ArgumentNullException ("buffer");
2417 if (offset < 0 || offset > buffer.Length)
2418 throw new ArgumentOutOfRangeException ("offset");
2420 if (size < 0 || offset + size > buffer.Length)
2421 throw new ArgumentOutOfRangeException ("size");
2423 return Receive_nochecks (buffer, offset, size, flags, out error);
2426 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2427 private extern static int Receive_internal (IntPtr sock,
2432 public int Receive (IList<ArraySegment<byte>> buffers)
2437 ret = Receive (buffers, SocketFlags.None, out error);
2438 if (error != SocketError.Success) {
2439 throw new SocketException ((int)error);
2445 [CLSCompliant (false)]
2446 public int Receive (IList<ArraySegment<byte>> buffers,
2447 SocketFlags socketFlags)
2452 ret = Receive (buffers, socketFlags, out error);
2453 if (error != SocketError.Success) {
2454 throw new SocketException ((int)error);
2460 [CLSCompliant (false)]
2461 public int Receive (IList<ArraySegment<byte>> buffers,
2462 SocketFlags socketFlags,
2463 out SocketError errorCode)
2465 if (disposed && closed)
2466 throw new ObjectDisposedException (GetType ().ToString ());
2468 if (buffers == null ||
2469 buffers.Count == 0) {
2470 throw new ArgumentNullException ("buffers");
2473 int numsegments = buffers.Count;
2477 /* Only example I can find of sending a byte
2478 * array reference directly into an internal
2480 * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
2481 * so taking a lead from that...
2483 WSABUF[] bufarray = new WSABUF[numsegments];
2484 GCHandle[] gch = new GCHandle[numsegments];
2486 for(int i = 0; i < numsegments; i++) {
2487 ArraySegment<byte> segment = buffers[i];
2488 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2489 bufarray[i].len = segment.Count;
2490 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2494 ret = Receive_internal (socket, bufarray,
2498 for(int i = 0; i < numsegments; i++) {
2499 if (gch[i].IsAllocated) {
2505 errorCode = (SocketError)nativeError;
2511 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
2513 if (disposed && closed)
2514 throw new ObjectDisposedException (GetType ().ToString ());
2516 // We do not support recv into multiple buffers yet
2517 if (e.BufferList != null)
2518 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
2519 if (e.RemoteEndPoint == null)
2520 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2522 e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
2524 // We always return true for now
2529 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
2531 if (disposed && closed)
2532 throw new ObjectDisposedException (GetType ().ToString ());
2535 throw new ArgumentNullException ("buffer");
2537 if (remoteEP == null)
2538 throw new ArgumentNullException ("remoteEP");
2540 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
2543 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
2545 if (disposed && closed)
2546 throw new ObjectDisposedException (GetType ().ToString ());
2549 throw new ArgumentNullException ("buffer");
2551 if (remoteEP == null)
2552 throw new ArgumentNullException ("remoteEP");
2554 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
2557 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
2558 ref EndPoint remoteEP)
2560 if (disposed && closed)
2561 throw new ObjectDisposedException (GetType ().ToString ());
2564 throw new ArgumentNullException ("buffer");
2566 if (remoteEP == null)
2567 throw new ArgumentNullException ("remoteEP");
2569 if (size < 0 || size > buffer.Length)
2570 throw new ArgumentOutOfRangeException ("size");
2572 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
2575 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2576 private extern static int RecvFrom_internal(IntPtr sock,
2581 ref SocketAddress sockaddr,
2584 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
2585 ref EndPoint remoteEP)
2587 if (disposed && closed)
2588 throw new ObjectDisposedException (GetType ().ToString ());
2591 throw new ArgumentNullException ("buffer");
2593 if (remoteEP == null)
2594 throw new ArgumentNullException ("remoteEP");
2596 if (offset < 0 || offset > buffer.Length)
2597 throw new ArgumentOutOfRangeException ("offset");
2599 if (size < 0 || offset + size > buffer.Length)
2600 throw new ArgumentOutOfRangeException ("size");
2602 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
2605 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
2606 ref EndPoint remote_end)
2609 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
2612 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
2613 ref EndPoint remote_end, bool throwOnError, out int error)
2615 SocketAddress sockaddr = remote_end.Serialize();
2616 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
2617 SocketError err = (SocketError) error;
2619 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2621 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
2623 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
2624 error = (int) SocketError.TimedOut;
2629 throw new SocketException (error);
2639 // If sockaddr is null then we're a connection
2640 // oriented protocol and should ignore the
2641 // remote_end parameter (see MSDN
2642 // documentation for Socket.ReceiveFrom(...) )
2644 if ( sockaddr != null ) {
2645 // Stupidly, EndPoint.Create() is an
2647 remote_end = remote_end.Create (sockaddr);
2650 seed_endpoint = remote_end;
2656 [MonoTODO ("Not implemented")]
2657 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
2659 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2660 if (disposed && closed)
2661 throw new ObjectDisposedException (GetType ().ToString ());
2663 throw new NotImplementedException ();
2666 [MonoTODO ("Not implemented")]
2667 public int ReceiveMessageFrom (byte[] buffer, int offset,
2669 ref SocketFlags socketFlags,
2670 ref EndPoint remoteEP,
2671 out IPPacketInformation ipPacketInformation)
2673 if (disposed && closed)
2674 throw new ObjectDisposedException (GetType ().ToString ());
2677 throw new ArgumentNullException ("buffer");
2679 if (remoteEP == null)
2680 throw new ArgumentNullException ("remoteEP");
2682 if (offset < 0 || offset > buffer.Length)
2683 throw new ArgumentOutOfRangeException ("offset");
2685 if (size < 0 || offset + size > buffer.Length)
2686 throw new ArgumentOutOfRangeException ("size");
2688 /* FIXME: figure out how we get hold of the
2689 * IPPacketInformation
2691 throw new NotImplementedException ();
2694 [MonoTODO ("Not implemented")]
2695 public bool SendPacketsAsync (SocketAsyncEventArgs e)
2697 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2699 if (disposed && closed)
2700 throw new ObjectDisposedException (GetType ().ToString ());
2702 throw new NotImplementedException ();
2707 public int Send (byte [] buf)
2709 if (disposed && closed)
2710 throw new ObjectDisposedException (GetType ().ToString ());
2713 throw new ArgumentNullException ("buf");
2717 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2719 if (error != SocketError.Success)
2720 throw new SocketException ((int) error);
2725 public int Send (byte [] buf, SocketFlags flags)
2727 if (disposed && closed)
2728 throw new ObjectDisposedException (GetType ().ToString ());
2731 throw new ArgumentNullException ("buf");
2735 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
2737 if (error != SocketError.Success)
2738 throw new SocketException ((int) error);
2743 public int Send (byte [] buf, int size, SocketFlags flags)
2745 if (disposed && closed)
2746 throw new ObjectDisposedException (GetType ().ToString ());
2749 throw new ArgumentNullException ("buf");
2751 if (size < 0 || size > buf.Length)
2752 throw new ArgumentOutOfRangeException ("size");
2756 int ret = Send_nochecks (buf, 0, size, flags, out error);
2758 if (error != SocketError.Success)
2759 throw new SocketException ((int) error);
2764 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
2766 if (disposed && closed)
2767 throw new ObjectDisposedException (GetType ().ToString ());
2770 throw new ArgumentNullException ("buffer");
2772 if (offset < 0 || offset > buf.Length)
2773 throw new ArgumentOutOfRangeException ("offset");
2775 if (size < 0 || offset + size > buf.Length)
2776 throw new ArgumentOutOfRangeException ("size");
2780 int ret = Send_nochecks (buf, offset, size, flags, out error);
2782 if (error != SocketError.Success)
2783 throw new SocketException ((int) error);
2789 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2791 if (disposed && closed)
2792 throw new ObjectDisposedException (GetType ().ToString ());
2795 throw new ArgumentNullException ("buffer");
2797 if (offset < 0 || offset > buf.Length)
2798 throw new ArgumentOutOfRangeException ("offset");
2800 if (size < 0 || offset + size > buf.Length)
2801 throw new ArgumentOutOfRangeException ("size");
2803 return Send_nochecks (buf, offset, size, flags, out error);
2806 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2807 private extern static int Send_internal (IntPtr sock,
2812 public int Send (IList<ArraySegment<byte>> buffers)
2817 ret = Send (buffers, SocketFlags.None, out error);
2818 if (error != SocketError.Success) {
2819 throw new SocketException ((int)error);
2825 public int Send (IList<ArraySegment<byte>> buffers,
2826 SocketFlags socketFlags)
2831 ret = Send (buffers, socketFlags, out error);
2832 if (error != SocketError.Success) {
2833 throw new SocketException ((int)error);
2839 [CLSCompliant (false)]
2840 public int Send (IList<ArraySegment<byte>> buffers,
2841 SocketFlags socketFlags,
2842 out SocketError errorCode)
2844 if (disposed && closed) {
2845 throw new ObjectDisposedException (GetType ().ToString ());
2848 if (buffers == null) {
2849 throw new ArgumentNullException ("buffers");
2852 if (buffers.Count == 0) {
2853 throw new ArgumentException ("Buffer is empty", "buffers");
2856 int numsegments = buffers.Count;
2860 WSABUF[] bufarray = new WSABUF[numsegments];
2861 GCHandle[] gch = new GCHandle[numsegments];
2863 for(int i = 0; i < numsegments; i++) {
2864 ArraySegment<byte> segment = buffers[i];
2865 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2866 bufarray[i].len = segment.Count;
2867 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2871 ret = Send_internal (socket, bufarray,
2875 for(int i = 0; i < numsegments; i++) {
2876 if (gch[i].IsAllocated) {
2882 errorCode = (SocketError)nativeError;
2886 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2887 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
2889 public void SendFile (string fileName)
2891 if (disposed && closed)
2892 throw new ObjectDisposedException (GetType ().ToString ());
2895 throw new NotSupportedException ();
2898 throw new InvalidOperationException ();
2900 SendFile (fileName, null, null, 0);
2903 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
2905 if (disposed && closed)
2906 throw new ObjectDisposedException (GetType ().ToString ());
2909 throw new NotSupportedException ();
2912 throw new InvalidOperationException ();
2914 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
2915 SocketException exc = new SocketException ();
2916 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
2917 throw new FileNotFoundException ();
2922 public bool SendToAsync (SocketAsyncEventArgs e)
2924 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2926 if (disposed && closed)
2927 throw new ObjectDisposedException (GetType ().ToString ());
2928 if (e.RemoteEndPoint == null)
2929 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2931 e.DoOperation (SocketAsyncOperation.SendTo, this);
2933 // We always return true for now
2938 public int SendTo (byte [] buffer, 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, SocketFlags.None, remote_end);
2952 public int SendTo (byte [] buffer, 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 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2966 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2968 if (disposed && closed)
2969 throw new ObjectDisposedException (GetType ().ToString ());
2972 throw new ArgumentNullException ("buffer");
2974 if (remote_end == null)
2975 throw new ArgumentNullException ("remote_end");
2977 if (size < 0 || size > buffer.Length)
2978 throw new ArgumentOutOfRangeException ("size");
2980 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2983 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2984 private extern static int SendTo_internal(IntPtr sock,
2992 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2993 EndPoint remote_end)
2995 if (disposed && closed)
2996 throw new ObjectDisposedException (GetType ().ToString ());
2999 throw new ArgumentNullException ("buffer");
3001 if (remote_end == null)
3002 throw new ArgumentNullException("remote_end");
3004 if (offset < 0 || offset > buffer.Length)
3005 throw new ArgumentOutOfRangeException ("offset");
3007 if (size < 0 || offset + size > buffer.Length)
3008 throw new ArgumentOutOfRangeException ("size");
3010 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
3013 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
3014 EndPoint remote_end)
3016 SocketAddress sockaddr = remote_end.Serialize ();
3020 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
3022 SocketError err = (SocketError) error;
3024 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
3027 throw new SocketException (error);
3036 seed_endpoint = remote_end;
3041 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
3043 if (disposed && closed)
3044 throw new ObjectDisposedException (GetType ().ToString ());
3046 // I'd throw an ArgumentNullException, but this is what MS does.
3047 if (optionValue == null)
3048 throw new SocketException ((int) SocketError.Fault,
3049 "Error trying to dereference an invalid pointer");
3053 SetSocketOption_internal (socket, optionLevel, optionName, null,
3054 optionValue, 0, out error);
3057 if (error == (int) SocketError.InvalidArgument)
3058 throw new ArgumentException ();
3059 throw new SocketException (error);
3063 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
3065 if (disposed && closed)
3066 throw new ObjectDisposedException (GetType ().ToString ());
3068 // NOTE: if a null is passed, the byte[] overload is used instead...
3069 if (optionValue == null)
3070 throw new ArgumentNullException("optionValue");
3074 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
3075 LingerOption linger = optionValue as LingerOption;
3078 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
3080 throw new ArgumentException ("optionValue");
3082 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
3083 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
3084 MulticastOption multicast = optionValue as MulticastOption;
3085 if (multicast == null)
3087 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
3089 throw new ArgumentException ("optionValue");
3091 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
3092 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
3093 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
3094 if (multicast == null)
3096 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
3098 throw new ArgumentException ("optionValue");
3100 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
3103 throw new ArgumentException ("Invalid value specified.", "optionValue");
3105 throw new ArgumentException ("optionValue");
3110 if (error == (int) SocketError.InvalidArgument)
3111 throw new ArgumentException ();
3112 throw new SocketException (error);
3117 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
3119 if (disposed && closed)
3120 throw new ObjectDisposedException (GetType ().ToString ());
3123 int int_val = (optionValue) ? 1 : 0;
3124 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
3126 if (error == (int) SocketError.InvalidArgument)
3127 throw new ArgumentException ();
3128 throw new SocketException (error);
3134 public override int GetHashCode ()
3137 // The socket is not suitable to serve as a hash code,
3138 // because it will change during its lifetime, but
3139 // this is how MS.NET 1.1 implemented this method.
3140 return (int) socket;