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.Collections.Generic;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
42 using System.Threading;
43 using System.Reflection;
45 using System.Net.Configuration;
49 using System.Net.NetworkInformation;
52 namespace System.Net.Sockets
54 public partial class Socket : IDisposable
56 enum SocketOperation {
73 [StructLayout (LayoutKind.Sequential)]
80 [StructLayout (LayoutKind.Sequential)]
81 private sealed class SocketAsyncResult: IAsyncResult
83 /* Same structure in the runtime */
85 Keep this in sync with MonoSocketAsyncResult in
86 metadata/socket-io.h and ProcessAsyncReader
87 in System.Diagnostics/Process.cs.
93 AsyncCallback callback;
94 WaitHandle waithandle;
96 Exception delayedException;
98 public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
99 public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
100 public int Offset; // Receive,ReceiveFrom,Send,SendTo
101 public int Size; // Receive,ReceiveFrom,Send,SendTo
102 public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
103 public Socket AcceptSocket; // AcceptReceive
104 public IPAddress[] Addresses; // Connect
105 public int Port; // Connect
107 public IList<ArraySegment<byte>> Buffers; // Receive, Send
109 public object Buffers; // Reserve this slot in older profiles
111 public bool ReuseSocket; // Disconnect
119 public bool blocking;
121 SocketOperation operation;
123 public int EndCalled;
125 public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
128 this.blocking = sock.blocking;
129 this.handle = sock.socket;
131 this.callback = callback;
132 this.operation = operation;
133 SockFlags = SocketFlags.None;
136 public void CheckIfThrowDelayedException ()
138 if (delayedException != null) {
139 Sock.connected = false;
140 throw delayedException;
144 Sock.connected = false;
145 throw new SocketException (error);
149 void CompleteAllOnDispose (Queue queue)
151 object [] pending = queue.ToArray ();
155 for (int i = 0; i < pending.Length; i++) {
156 SocketAsyncResult ares = (SocketAsyncResult) pending [i];
157 cb = new WaitCallback (ares.CompleteDisposed);
158 ThreadPool.QueueUserWorkItem (cb, null);
160 if (pending.Length == 0)
164 void CompleteDisposed (object unused)
169 public void Complete ()
171 if (operation != SocketOperation.Receive && Sock.disposed)
172 delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
177 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
179 } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
184 SocketAsyncCall sac = null;
185 SocketAsyncResult req = null;
187 queue.Dequeue (); // remove ourselves
188 if (queue.Count > 0) {
189 req = (SocketAsyncResult) queue.Peek ();
190 if (!Sock.disposed) {
191 Worker worker = new Worker (req);
192 sac = GetDelegate (worker, req.operation);
194 CompleteAllOnDispose (queue);
200 sac.BeginInvoke (null, req);
203 if (callback != null)
208 SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
211 case SocketOperation.Receive:
212 return new SocketAsyncCall (worker.Receive);
213 case SocketOperation.ReceiveFrom:
214 return new SocketAsyncCall (worker.ReceiveFrom);
215 case SocketOperation.Send:
216 return new SocketAsyncCall (worker.Send);
217 case SocketOperation.SendTo:
218 return new SocketAsyncCall (worker.SendTo);
220 return null; // never happens
224 public void Complete (bool synch)
226 completed_sync = synch;
230 public void Complete (int total)
236 public void Complete (Exception e, bool synch)
238 completed_sync = synch;
239 delayedException = e;
243 public void Complete (Exception e)
245 delayedException = e;
249 public void Complete (Socket s)
255 public void Complete (Socket s, int total)
262 public object AsyncState {
268 public WaitHandle AsyncWaitHandle {
271 if (waithandle == null)
272 waithandle = new ManualResetEvent (completed);
282 public bool CompletedSynchronously {
284 return(completed_sync);
288 public bool IsCompleted {
295 if (waithandle != null && value) {
296 ((ManualResetEvent) waithandle).Set ();
302 public Socket Socket {
309 get { return total; }
310 set { total = value; }
313 public SocketError ErrorCode
317 SocketException ex = delayedException as SocketException;
320 return(ex.SocketErrorCode);
323 return((SocketError)error);
325 return(SocketError.Success);
330 private sealed class Worker
332 SocketAsyncResult result;
334 public Worker (SocketAsyncResult ares)
339 public void Accept ()
341 Socket acc_socket = null;
343 acc_socket = result.Sock.Accept ();
344 } catch (Exception e) {
349 result.Complete (acc_socket);
352 /* only used in 2.0 profile and newer, but
353 * leave in older profiles to keep interface
354 * to runtime consistent
356 public void AcceptReceive ()
358 Socket acc_socket = null;
361 if (result.AcceptSocket == null) {
362 acc_socket = result.Sock.Accept ();
364 acc_socket = result.AcceptSocket;
365 result.Sock.Accept (acc_socket);
367 } catch (Exception e) {
372 /* It seems the MS runtime
373 * special-cases 0-length requested
374 * receive data. See bug 464201.
377 if (result.Size > 0) {
381 total = acc_socket.Receive_nochecks (result.Buffer,
386 } catch (Exception e) {
392 result.Complete (acc_socket, total);
395 public void Connect ()
397 /* If result.EndPoint is non-null,
398 * this is the standard one-address
399 * connect attempt. Otherwise
400 * Addresses must be non-null and
401 * contain a list of addresses to try
402 * to connect to; the first one to
403 * succeed causes the rest of the list
406 if (result.EndPoint != null) {
408 if (!result.Sock.Blocking) {
410 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
412 result.Sock.connected = true;
414 result.Complete (new SocketException (success));
418 result.Sock.seed_endpoint = result.EndPoint;
419 result.Sock.Connect (result.EndPoint);
420 result.Sock.connected = true;
422 } catch (Exception e) {
428 } else if (result.Addresses != null) {
429 int error = (int) SocketError.InProgress; // why?
430 foreach(IPAddress address in result.Addresses) {
431 IPEndPoint iep = new IPEndPoint (address, result.Port);
432 SocketAddress serial = iep.Serialize ();
434 Socket.Connect_internal (result.Sock.socket, serial, out error);
436 result.Sock.connected = true;
437 result.Sock.seed_endpoint = iep;
440 } else if (error != (int)SocketError.InProgress &&
441 error != (int)SocketError.WouldBlock) {
445 if (!result.Sock.Blocking) {
447 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
449 result.Sock.connected = true;
450 result.Sock.seed_endpoint = iep;
457 result.Complete (new SocketException (error));
459 result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
463 /* Also only used in 2.0 profile and newer */
464 public void Disconnect ()
468 result.Sock.Disconnect (result.ReuseSocket);
469 } catch (Exception e) {
475 result.Complete (new SocketException ((int)SocketError.Fault));
479 public void Receive ()
481 // Actual recv() done in the runtime
485 public void ReceiveFrom ()
489 total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
493 ref result.EndPoint);
494 } catch (Exception e) {
499 result.Complete (total);
502 public void ReceiveGeneric ()
509 total = result.Sock.Receive (result.Buffers, result.SockFlags, out error);
510 } catch (Exception e) {
515 result.Complete (total);
517 result.Complete (new SocketException ((int)SocketError.Fault));
523 void UpdateSendValues (int last_sent)
525 if (result.error == 0) {
526 send_so_far += last_sent;
527 result.Offset += last_sent;
528 result.Size -= last_sent;
534 // Actual send() done in the runtime
535 if (result.error == 0) {
536 UpdateSendValues (result.Total);
537 if (result.Sock.disposed) {
542 if (result.Size > 0) {
543 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
544 sac.BeginInvoke (null, result);
545 return; // Have to finish writing everything. See bug #74475.
547 result.Total = send_so_far;
552 public void SendTo ()
556 total = result.Sock.SendTo_nochecks (result.Buffer,
562 UpdateSendValues (total);
563 if (result.Size > 0) {
564 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
565 sac.BeginInvoke (null, result);
566 return; // Have to finish writing everything. See bug #74475.
568 result.Total = send_so_far;
569 } catch (Exception e) {
577 public void SendGeneric ()
584 total = result.Sock.Send (result.Buffers, result.SockFlags, out error);
585 } catch (Exception e) {
590 result.Complete (total);
592 result.Complete (new SocketException ((int)SocketError.Fault));
598 private Queue readQ = new Queue (2);
599 private Queue writeQ = new Queue (2);
601 delegate void SocketAsyncCall ();
604 private bool islistening;
605 private bool useoverlappedIO;
609 static void AddSockets (ArrayList sockets, IList list, string name)
612 foreach (Socket sock in list) {
613 if (sock == null) // MS throws a NullRef
614 throw new ArgumentNullException ("name", "Contains a null element");
622 [MethodImplAttribute(MethodImplOptions.InternalCall)]
623 private extern static void Select_internal (ref Socket [] sockets,
627 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
629 ArrayList list = new ArrayList ();
630 AddSockets (list, checkRead, "checkRead");
631 AddSockets (list, checkWrite, "checkWrite");
632 AddSockets (list, checkError, "checkError");
634 if (list.Count == 3) {
635 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
636 "All the lists are null or empty.");
641 * The 'sockets' array contains: READ socket 0-n, null,
642 * WRITE socket 0-n, null,
643 * ERROR socket 0-n, null
645 Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
646 Select_internal (ref sockets, microSeconds, out error);
649 throw new SocketException (error);
651 if (sockets == null) {
652 if (checkRead != null)
654 if (checkWrite != null)
656 if (checkError != null)
662 int count = sockets.Length;
663 IList currentList = checkRead;
665 for (int i = 0; i < count; i++) {
666 Socket sock = sockets [i];
667 if (sock == null) { // separator
668 if (currentList != null) {
669 // Remove non-signaled sockets after the current one
670 int to_remove = currentList.Count - currentIdx;
671 for (int k = 0; k < to_remove; k++)
672 currentList.RemoveAt (currentIdx);
674 currentList = (mode == 0) ? checkWrite : checkError;
680 if (mode == 1 && currentList == checkWrite && !sock.connected) {
681 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
682 sock.connected = true;
685 // Remove non-signaled sockets before the current one
686 //int max = currentList.Count;
687 while (((Socket) currentList [currentIdx]) != sock) {
688 currentList.RemoveAt (currentIdx);
694 // private constructor used by Accept, which already
695 // has a socket handle to use
696 private Socket(AddressFamily family, SocketType type,
697 ProtocolType proto, IntPtr sock)
699 address_family=family;
707 private void SocketDefaults ()
711 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
712 address_family == AddressFamily.InterNetworkV6 */) {
713 /* This is the default, but it
714 * probably has nasty side
715 * effects on Linux, as the
716 * socket option is kludged by
717 * turning on or off PMTU
720 this.DontFragment = false;
724 // Microsoft sets these to 8192, but we are going to keep them
725 // both to the OS defaults as these have a big performance impact.
726 // on WebClient performance.
728 //this.ReceiveBufferSize = 8192;
729 //this.SendBufferSize = 8192;
730 } catch (SocketException) {
738 public Socket (SocketInformation socketInformation)
740 throw new NotImplementedException ("SocketInformation not figured out yet");
742 // ifdef to avoid the warnings.
744 //address_family = socketInformation.address_family;
745 //socket_type = socketInformation.socket_type;
746 //protocol_type = socketInformation.protocol_type;
747 address_family = AddressFamily.InterNetwork;
748 socket_type = SocketType.Stream;
749 protocol_type = ProtocolType.IP;
752 socket = Socket_internal (address_family, socket_type, protocol_type, out error);
754 throw new SocketException (error);
762 // Returns the amount of data waiting to be read on socket
763 [MethodImplAttribute(MethodImplOptions.InternalCall)]
764 private extern static int Available_internal(IntPtr socket, out int error);
767 public int Available {
769 if (disposed && closed)
770 throw new ObjectDisposedException (GetType ().ToString ());
774 ret = Available_internal(socket, out error);
777 throw new SocketException (error);
785 public bool DontFragment {
787 if (disposed && closed) {
788 throw new ObjectDisposedException (GetType ().ToString ());
793 if (address_family == AddressFamily.InterNetwork) {
794 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
795 } else if (address_family == AddressFamily.InterNetworkV6) {
796 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
798 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
801 return(dontfragment);
804 if (disposed && closed) {
805 throw new ObjectDisposedException (GetType ().ToString ());
808 if (address_family == AddressFamily.InterNetwork) {
809 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
810 } else if (address_family == AddressFamily.InterNetworkV6) {
811 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
813 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
818 public bool EnableBroadcast {
820 if (disposed && closed) {
821 throw new ObjectDisposedException (GetType ().ToString ());
824 if (protocol_type != ProtocolType.Udp) {
825 throw new SocketException ((int)SocketError.ProtocolOption);
828 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
831 if (disposed && closed) {
832 throw new ObjectDisposedException (GetType ().ToString ());
835 if (protocol_type != ProtocolType.Udp) {
836 throw new SocketException ((int)SocketError.ProtocolOption);
839 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
843 public bool ExclusiveAddressUse {
845 if (disposed && closed) {
846 throw new ObjectDisposedException (GetType ().ToString ());
849 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
852 if (disposed && closed) {
853 throw new ObjectDisposedException (GetType ().ToString ());
856 throw new InvalidOperationException ("Bind has already been called for this socket");
859 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
863 public bool IsBound {
869 public LingerOption LingerState {
871 if (disposed && closed) {
872 throw new ObjectDisposedException (GetType ().ToString ());
875 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
878 if (disposed && closed) {
879 throw new ObjectDisposedException (GetType ().ToString ());
882 SetSocketOption (SocketOptionLevel.Socket,
883 SocketOptionName.Linger,
888 public bool MulticastLoopback {
890 if (disposed && closed) {
891 throw new ObjectDisposedException (GetType ().ToString ());
894 /* Even though this option can be set
895 * for TCP sockets on Linux, throw
896 * this exception anyway to be
897 * compatible (the MSDN docs say
898 * "Setting this property on a
899 * Transmission Control Protocol (TCP)
900 * socket will have no effect." but
901 * the MS runtime throws the
904 if (protocol_type == ProtocolType.Tcp) {
905 throw new SocketException ((int)SocketError.ProtocolOption);
908 bool multicastloopback;
910 if (address_family == AddressFamily.InterNetwork) {
911 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
912 } else if (address_family == AddressFamily.InterNetworkV6) {
913 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
915 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
918 return(multicastloopback);
921 if (disposed && closed) {
922 throw new ObjectDisposedException (GetType ().ToString ());
925 /* Even though this option can be set
926 * for TCP sockets on Linux, throw
927 * this exception anyway to be
928 * compatible (the MSDN docs say
929 * "Setting this property on a
930 * Transmission Control Protocol (TCP)
931 * socket will have no effect." but
932 * the MS runtime throws the
935 if (protocol_type == ProtocolType.Tcp) {
936 throw new SocketException ((int)SocketError.ProtocolOption);
939 if (address_family == AddressFamily.InterNetwork) {
940 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
941 } else if (address_family == AddressFamily.InterNetworkV6) {
942 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
944 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
950 [MonoTODO ("This doesn't do anything on Mono yet")]
951 public bool UseOnlyOverlappedIO {
953 return(useoverlappedIO);
956 useoverlappedIO = value;
961 public IntPtr Handle {
968 // Returns the local endpoint details in addr and port
969 [MethodImplAttribute(MethodImplOptions.InternalCall)]
970 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
973 // Wish: support non-IP endpoints.
974 public EndPoint LocalEndPoint {
976 if (disposed && closed)
977 throw new ObjectDisposedException (GetType ().ToString ());
980 * If the seed EndPoint is null, Connect, Bind,
981 * etc has not yet been called. MS returns null
984 if (seed_endpoint == null)
990 sa=LocalEndPoint_internal(socket, out error);
993 throw new SocketException (error);
995 return seed_endpoint.Create (sa);
999 public SocketType SocketType {
1001 return(socket_type);
1006 public int SendTimeout {
1008 if (disposed && closed)
1009 throw new ObjectDisposedException (GetType ().ToString ());
1011 return (int)GetSocketOption(
1012 SocketOptionLevel.Socket,
1013 SocketOptionName.SendTimeout);
1016 if (disposed && closed)
1017 throw new ObjectDisposedException (GetType ().ToString ());
1020 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1022 /* According to the MSDN docs we
1023 * should adjust values between 1 and
1024 * 499 to 500, but the MS runtime
1031 SocketOptionLevel.Socket,
1032 SocketOptionName.SendTimeout, value);
1036 public int ReceiveTimeout {
1038 if (disposed && closed)
1039 throw new ObjectDisposedException (GetType ().ToString ());
1041 return (int)GetSocketOption(
1042 SocketOptionLevel.Socket,
1043 SocketOptionName.ReceiveTimeout);
1046 if (disposed && closed)
1047 throw new ObjectDisposedException (GetType ().ToString ());
1050 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1057 SocketOptionLevel.Socket,
1058 SocketOptionName.ReceiveTimeout, value);
1062 public bool AcceptAsync (SocketAsyncEventArgs e)
1064 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1066 if (disposed && closed)
1067 throw new ObjectDisposedException (GetType ().ToString ());
1069 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
1071 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
1072 if (e.BufferList != null)
1073 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1075 throw new ArgumentOutOfRangeException ("e.Count");
1077 Socket acceptSocket = e.AcceptSocket;
1078 if (acceptSocket != null) {
1079 if (acceptSocket.IsBound || acceptSocket.Connected)
1080 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
1082 e.AcceptSocket = new Socket (AddressFamily, SocketType, ProtocolType);
1085 e.DoOperation (SocketAsyncOperation.Accept, this);
1087 ((IDisposable)e).Dispose ();
1091 // We always return true for now
1096 // Creates a new system socket, returning the handle
1097 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1098 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
1100 public Socket Accept() {
1101 if (disposed && closed)
1102 throw new ObjectDisposedException (GetType ().ToString ());
1105 IntPtr sock = (IntPtr) (-1);
1106 blocking_thread = Thread.CurrentThread;
1108 sock = Accept_internal(socket, out error, blocking);
1109 } catch (ThreadAbortException) {
1111 Thread.ResetAbort ();
1112 error = (int) SocketError.Interrupted;
1115 blocking_thread = null;
1119 throw new SocketException (error);
1121 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
1122 this.ProtocolType, sock);
1124 accepted.seed_endpoint = this.seed_endpoint;
1125 accepted.Blocking = this.Blocking;
1129 internal void Accept (Socket acceptSocket)
1131 if (disposed && closed)
1132 throw new ObjectDisposedException (GetType ().ToString ());
1135 IntPtr sock = (IntPtr)(-1);
1136 blocking_thread = Thread.CurrentThread;
1139 sock = Accept_internal (socket, out error, blocking);
1140 } catch (ThreadAbortException) {
1142 Thread.ResetAbort ();
1143 error = (int)SocketError.Interrupted;
1146 blocking_thread = null;
1150 throw new SocketException (error);
1152 acceptSocket.address_family = this.AddressFamily;
1153 acceptSocket.socket_type = this.SocketType;
1154 acceptSocket.protocol_type = this.ProtocolType;
1155 acceptSocket.socket = sock;
1156 acceptSocket.connected = true;
1157 acceptSocket.seed_endpoint = this.seed_endpoint;
1158 acceptSocket.Blocking = this.Blocking;
1160 /* FIXME: figure out what if anything else
1165 public IAsyncResult BeginAccept(AsyncCallback callback,
1168 if (disposed && closed)
1169 throw new ObjectDisposedException (GetType ().ToString ());
1172 /* FIXME: check the 1.1 docs for this too */
1173 if (!isbound || !islistening)
1174 throw new InvalidOperationException ();
1177 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1178 Worker worker = new Worker (req);
1179 SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1180 sac.BeginInvoke (null, req);
1185 public IAsyncResult BeginAccept (int receiveSize,
1186 AsyncCallback callback,
1189 if (disposed && closed)
1190 throw new ObjectDisposedException (GetType ().ToString ());
1192 if (receiveSize < 0)
1193 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1195 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1196 Worker worker = new Worker (req);
1197 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1199 req.Buffer = new byte[receiveSize];
1201 req.Size = receiveSize;
1202 req.SockFlags = SocketFlags.None;
1204 sac.BeginInvoke (null, req);
1208 public IAsyncResult BeginAccept (Socket acceptSocket,
1210 AsyncCallback callback,
1213 if (disposed && closed)
1214 throw new ObjectDisposedException (GetType ().ToString ());
1216 if (receiveSize < 0)
1217 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1219 if (acceptSocket != null) {
1220 if (acceptSocket.disposed && acceptSocket.closed)
1221 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
1223 if (acceptSocket.IsBound)
1224 throw new InvalidOperationException ();
1226 /* For some reason the MS runtime
1227 * barfs if the new socket is not TCP,
1228 * even though it's just about to blow
1229 * away all those parameters
1231 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
1232 throw new SocketException ((int)SocketError.InvalidArgument);
1235 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1236 Worker worker = new Worker (req);
1237 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1239 req.Buffer = new byte[receiveSize];
1241 req.Size = receiveSize;
1242 req.SockFlags = SocketFlags.None;
1243 req.AcceptSocket = acceptSocket;
1245 sac.BeginInvoke (null, req);
1250 public IAsyncResult BeginConnect(EndPoint end_point,
1251 AsyncCallback callback,
1254 if (disposed && closed)
1255 throw new ObjectDisposedException (GetType ().ToString ());
1257 if (end_point == null)
1258 throw new ArgumentNullException ("end_point");
1260 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1261 req.EndPoint = end_point;
1263 // Bug #75154: Connect() should not succeed for .Any addresses.
1264 if (end_point is IPEndPoint) {
1265 IPEndPoint ep = (IPEndPoint) end_point;
1266 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
1267 req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
1274 SocketAddress serial = end_point.Serialize ();
1275 Connect_internal (socket, serial, out error);
1279 req.Complete (true);
1280 } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
1283 req.Complete (new SocketException (error), true);
1287 if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
1290 Worker worker = new Worker (req);
1291 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1292 sac.BeginInvoke (null, req);
1299 public IAsyncResult BeginConnect (IPAddress address, int port,
1300 AsyncCallback callback,
1303 if (disposed && closed)
1304 throw new ObjectDisposedException (GetType ().ToString ());
1306 if (address == null)
1307 throw new ArgumentNullException ("address");
1309 if (address.ToString ().Length == 0)
1310 throw new ArgumentException ("The length of the IP address is zero");
1313 throw new InvalidOperationException ();
1315 IPEndPoint iep = new IPEndPoint (address, port);
1316 return(BeginConnect (iep, callback, state));
1319 public IAsyncResult BeginConnect (IPAddress[] addresses,
1321 AsyncCallback callback,
1324 if (disposed && closed)
1325 throw new ObjectDisposedException (GetType ().ToString ());
1327 if (addresses == null)
1328 throw new ArgumentNullException ("addresses");
1330 if (this.AddressFamily != AddressFamily.InterNetwork &&
1331 this.AddressFamily != AddressFamily.InterNetworkV6)
1332 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1335 throw new InvalidOperationException ();
1337 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1338 req.Addresses = addresses;
1342 Worker worker = new Worker (req);
1343 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1344 sac.BeginInvoke (null, req);
1349 public IAsyncResult BeginConnect (string host, int port,
1350 AsyncCallback callback,
1353 if (disposed && closed)
1354 throw new ObjectDisposedException (GetType ().ToString ());
1357 throw new ArgumentNullException ("host");
1359 if (address_family != AddressFamily.InterNetwork &&
1360 address_family != AddressFamily.InterNetworkV6)
1361 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
1364 throw new InvalidOperationException ();
1366 IPAddress [] addresses = Dns.GetHostAddresses (host);
1367 return (BeginConnect (addresses, port, callback, state));
1370 public IAsyncResult BeginDisconnect (bool reuseSocket,
1371 AsyncCallback callback,
1374 if (disposed && closed)
1375 throw new ObjectDisposedException (GetType ().ToString ());
1377 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
1378 req.ReuseSocket = reuseSocket;
1380 Worker worker = new Worker (req);
1381 SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
1382 sac.BeginInvoke (null, req);
1388 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1390 SocketFlags socket_flags,
1391 AsyncCallback callback,
1394 if (disposed && closed)
1395 throw new ObjectDisposedException (GetType ().ToString ());
1398 throw new ArgumentNullException ("buffer");
1400 if (offset < 0 || offset > buffer.Length)
1401 throw new ArgumentOutOfRangeException ("offset");
1403 if (size < 0 || offset + size > buffer.Length)
1404 throw new ArgumentOutOfRangeException ("size");
1406 SocketAsyncResult req;
1408 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1409 req.Buffer = buffer;
1410 req.Offset = offset;
1412 req.SockFlags = socket_flags;
1413 readQ.Enqueue (req);
1414 if (readQ.Count == 1) {
1415 Worker worker = new Worker (req);
1416 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1417 sac.BeginInvoke (null, req);
1424 public IAsyncResult BeginReceive (byte[] buffer, int offset,
1425 int size, SocketFlags flags,
1426 out SocketError error,
1427 AsyncCallback callback,
1430 /* As far as I can tell from the docs and from
1431 * experimentation, a pointer to the
1432 * SocketError parameter is not supposed to be
1433 * saved for the async parts. And as we don't
1434 * set any socket errors in the setup code, we
1435 * just have to set it to Success.
1437 error = SocketError.Success;
1438 return (BeginReceive (buffer, offset, size, flags, callback, state));
1441 [CLSCompliant (false)]
1442 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1443 SocketFlags socketFlags,
1444 AsyncCallback callback,
1447 if (disposed && closed)
1448 throw new ObjectDisposedException (GetType ().ToString ());
1450 if (buffers == null)
1451 throw new ArgumentNullException ("buffers");
1453 SocketAsyncResult req;
1455 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
1456 req.Buffers = buffers;
1457 req.SockFlags = socketFlags;
1458 readQ.Enqueue (req);
1459 if (readQ.Count == 1) {
1460 Worker worker = new Worker (req);
1461 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
1462 sac.BeginInvoke (null, req);
1469 [CLSCompliant (false)]
1470 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1471 SocketFlags socketFlags,
1472 out SocketError errorCode,
1473 AsyncCallback callback,
1476 /* I assume the same SocketError semantics as
1479 errorCode = SocketError.Success;
1480 return (BeginReceive (buffers, socketFlags, callback, state));
1484 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1486 SocketFlags socket_flags,
1487 ref EndPoint remote_end,
1488 AsyncCallback callback,
1490 if (disposed && closed)
1491 throw new ObjectDisposedException (GetType ().ToString ());
1494 throw new ArgumentNullException ("buffer");
1497 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1500 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1502 if (offset + size > buffer.Length)
1503 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1505 SocketAsyncResult req;
1507 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1508 req.Buffer = buffer;
1509 req.Offset = offset;
1511 req.SockFlags = socket_flags;
1512 req.EndPoint = remote_end;
1513 readQ.Enqueue (req);
1514 if (readQ.Count == 1) {
1515 Worker worker = new Worker (req);
1516 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1517 sac.BeginInvoke (null, req);
1525 public IAsyncResult BeginReceiveMessageFrom (
1526 byte[] buffer, int offset, int size,
1527 SocketFlags socketFlags, ref EndPoint remoteEP,
1528 AsyncCallback callback, object state)
1530 if (disposed && closed)
1531 throw new ObjectDisposedException (GetType ().ToString ());
1534 throw new ArgumentNullException ("buffer");
1536 if (remoteEP == null)
1537 throw new ArgumentNullException ("remoteEP");
1539 if (offset < 0 || offset > buffer.Length)
1540 throw new ArgumentOutOfRangeException ("offset");
1542 if (size < 0 || offset + size > buffer.Length)
1543 throw new ArgumentOutOfRangeException ("size");
1545 throw new NotImplementedException ();
1549 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1550 AsyncCallback callback, object state)
1552 if (disposed && closed)
1553 throw new ObjectDisposedException (GetType ().ToString ());
1556 throw new ArgumentNullException ("buffer");
1559 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1562 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1564 if (offset + size > buffer.Length)
1565 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1568 /* TODO: Check this exception in the 1.1 profile */
1570 throw new SocketException ((int)SocketError.NotConnected);
1573 SocketAsyncResult req;
1575 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1576 req.Buffer = buffer;
1577 req.Offset = offset;
1579 req.SockFlags = socket_flags;
1580 writeQ.Enqueue (req);
1581 if (writeQ.Count == 1) {
1582 Worker worker = new Worker (req);
1583 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1584 sac.BeginInvoke (null, req);
1591 public IAsyncResult BeginSend (byte[] buffer, int offset,
1593 SocketFlags socketFlags,
1594 out SocketError errorCode,
1595 AsyncCallback callback,
1599 errorCode = SocketError.NotConnected;
1600 throw new SocketException ((int)errorCode);
1603 errorCode = SocketError.Success;
1605 return (BeginSend (buffer, offset, size, socketFlags, callback,
1609 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1610 SocketFlags socketFlags,
1611 AsyncCallback callback,
1614 if (disposed && closed)
1615 throw new ObjectDisposedException (GetType ().ToString ());
1617 if (buffers == null)
1618 throw new ArgumentNullException ("buffers");
1621 throw new SocketException ((int)SocketError.NotConnected);
1623 SocketAsyncResult req;
1625 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
1626 req.Buffers = buffers;
1627 req.SockFlags = socketFlags;
1628 writeQ.Enqueue (req);
1629 if (writeQ.Count == 1) {
1630 Worker worker = new Worker (req);
1631 SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
1632 sac.BeginInvoke (null, req);
1639 [CLSCompliant (false)]
1640 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1641 SocketFlags socketFlags,
1642 out SocketError errorCode,
1643 AsyncCallback callback,
1647 errorCode = SocketError.NotConnected;
1648 throw new SocketException ((int)errorCode);
1651 errorCode = SocketError.Success;
1652 return (BeginSend (buffers, socketFlags, callback, state));
1655 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
1657 sealed class SendFileAsyncResult : IAsyncResult {
1661 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
1667 public object AsyncState {
1668 get { return ares.AsyncState; }
1671 public WaitHandle AsyncWaitHandle {
1672 get { return ares.AsyncWaitHandle; }
1675 public bool CompletedSynchronously {
1676 get { return ares.CompletedSynchronously; }
1679 public bool IsCompleted {
1680 get { return ares.IsCompleted; }
1683 public SendFileHandler Delegate {
1687 public IAsyncResult Original {
1688 get { return ares; }
1692 public IAsyncResult BeginSendFile (string fileName,
1693 AsyncCallback callback,
1696 if (disposed && closed)
1697 throw new ObjectDisposedException (GetType ().ToString ());
1700 throw new NotSupportedException ();
1702 if (!File.Exists (fileName))
1703 throw new FileNotFoundException ();
1705 return BeginSendFile (fileName, null, null, 0, callback, state);
1708 public IAsyncResult BeginSendFile (string fileName,
1711 TransmitFileOptions flags,
1712 AsyncCallback callback,
1715 if (disposed && closed)
1716 throw new ObjectDisposedException (GetType ().ToString ());
1719 throw new NotSupportedException ();
1721 if (!File.Exists (fileName))
1722 throw new FileNotFoundException ();
1724 SendFileHandler d = new SendFileHandler (SendFile);
1725 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
1729 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1731 SocketFlags socket_flags,
1732 EndPoint remote_end,
1733 AsyncCallback callback,
1735 if (disposed && closed)
1736 throw new ObjectDisposedException (GetType ().ToString ());
1739 throw new ArgumentNullException ("buffer");
1742 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1745 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1747 if (offset + size > buffer.Length)
1748 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1750 SocketAsyncResult req;
1752 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1753 req.Buffer = buffer;
1754 req.Offset = offset;
1756 req.SockFlags = socket_flags;
1757 req.EndPoint = remote_end;
1758 writeQ.Enqueue (req);
1759 if (writeQ.Count == 1) {
1760 Worker worker = new Worker (req);
1761 SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1762 sac.BeginInvoke (null, req);
1768 // Creates a new system socket, returning the handle
1769 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1770 private extern static void Bind_internal(IntPtr sock,
1774 public void Bind(EndPoint local_end) {
1775 if (disposed && closed)
1776 throw new ObjectDisposedException (GetType ().ToString ());
1778 if (local_end == null)
1779 throw new ArgumentNullException("local_end");
1783 Bind_internal(socket, local_end.Serialize(), out error);
1785 throw new SocketException (error);
1791 seed_endpoint = local_end;
1795 public bool ConnectAsync (SocketAsyncEventArgs e)
1797 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1799 if (disposed && closed)
1800 throw new ObjectDisposedException (GetType ().ToString ());
1802 throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
1803 if (e.RemoteEndPoint == null)
1804 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1805 if (e.BufferList != null)
1806 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
1808 e.DoOperation (SocketAsyncOperation.Connect, this);
1810 // We always return true for now
1816 public void Connect (IPAddress address, int port)
1818 Connect (new IPEndPoint (address, port));
1821 public void Connect (IPAddress[] addresses, int port)
1823 if (disposed && closed)
1824 throw new ObjectDisposedException (GetType ().ToString ());
1826 if (addresses == null)
1827 throw new ArgumentNullException ("addresses");
1829 if (this.AddressFamily != AddressFamily.InterNetwork &&
1830 this.AddressFamily != AddressFamily.InterNetworkV6)
1831 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1834 throw new InvalidOperationException ();
1836 /* FIXME: do non-blocking sockets Poll here? */
1838 foreach (IPAddress address in addresses) {
1839 IPEndPoint iep = new IPEndPoint (address, port);
1840 SocketAddress serial = iep.Serialize ();
1842 Connect_internal (socket, serial, out error);
1845 seed_endpoint = iep;
1847 } else if (error != (int)SocketError.InProgress &&
1848 error != (int)SocketError.WouldBlock) {
1853 Poll (-1, SelectMode.SelectWrite);
1854 error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1857 seed_endpoint = iep;
1863 throw new SocketException (error);
1866 public void Connect (string host, int port)
1868 IPAddress [] addresses = Dns.GetHostAddresses (host);
1869 Connect (addresses, port);
1873 public bool DisconnectAsync (SocketAsyncEventArgs e)
1875 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1876 if (disposed && closed)
1877 throw new ObjectDisposedException (GetType ().ToString ());
1879 e.DoOperation (SocketAsyncOperation.Disconnect, this);
1884 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1885 private extern static void Disconnect_internal(IntPtr sock,
1889 /* According to the docs, the MS runtime will throw
1890 * PlatformNotSupportedException if the platform is
1891 * newer than w2k. We should be able to cope...
1893 public void Disconnect (bool reuseSocket)
1895 if (disposed && closed)
1896 throw new ObjectDisposedException (GetType ().ToString ());
1900 Disconnect_internal (socket, reuseSocket, out error);
1904 /* ERROR_NOT_SUPPORTED */
1905 throw new PlatformNotSupportedException ();
1907 throw new SocketException (error);
1914 /* Do managed housekeeping here... */
1918 [MonoTODO ("Not implemented")]
1919 public SocketInformation DuplicateAndClose (int targetProcessId)
1921 /* Need to serialize this socket into a
1922 * SocketInformation struct, but must study
1923 * the MS implementation harder to figure out
1924 * behaviour as documentation is lacking
1926 throw new NotImplementedException ();
1930 public Socket EndAccept (IAsyncResult result)
1935 return(EndAccept (out buffer, out bytes, result));
1939 public Socket EndAccept (out byte[] buffer,
1940 IAsyncResult asyncResult)
1944 return(EndAccept (out buffer, out bytes, asyncResult));
1953 Socket EndAccept (out byte[] buffer, out int bytesTransferred,
1954 IAsyncResult asyncResult)
1956 if (disposed && closed)
1957 throw new ObjectDisposedException (GetType ().ToString ());
1959 if (asyncResult == null)
1960 throw new ArgumentNullException ("asyncResult");
1962 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1964 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1966 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1967 throw InvalidAsyncOp ("EndAccept");
1968 if (!asyncResult.IsCompleted)
1969 asyncResult.AsyncWaitHandle.WaitOne ();
1971 req.CheckIfThrowDelayedException ();
1973 buffer = req.Buffer;
1974 bytesTransferred = req.Total;
1979 public void EndConnect (IAsyncResult result)
1981 if (disposed && closed)
1982 throw new ObjectDisposedException (GetType ().ToString ());
1985 throw new ArgumentNullException ("result");
1987 SocketAsyncResult req = result as SocketAsyncResult;
1989 throw new ArgumentException ("Invalid IAsyncResult", "result");
1991 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1992 throw InvalidAsyncOp ("EndConnect");
1993 if (!result.IsCompleted)
1994 result.AsyncWaitHandle.WaitOne();
1996 req.CheckIfThrowDelayedException();
2000 public void EndDisconnect (IAsyncResult asyncResult)
2002 if (disposed && closed)
2003 throw new ObjectDisposedException (GetType ().ToString ());
2005 if (asyncResult == null)
2006 throw new ArgumentNullException ("asyncResult");
2008 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2010 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2012 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2013 throw InvalidAsyncOp ("EndDisconnect");
2014 if (!asyncResult.IsCompleted)
2015 asyncResult.AsyncWaitHandle.WaitOne ();
2017 req.CheckIfThrowDelayedException ();
2021 public int EndReceive (IAsyncResult result)
2025 return (EndReceive (result, out error));
2033 int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2035 if (disposed && closed)
2036 throw new ObjectDisposedException (GetType ().ToString ());
2038 if (asyncResult == null)
2039 throw new ArgumentNullException ("asyncResult");
2041 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2043 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2045 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2046 throw InvalidAsyncOp ("EndReceive");
2047 if (!asyncResult.IsCompleted)
2048 asyncResult.AsyncWaitHandle.WaitOne ();
2050 errorCode = req.ErrorCode;
2051 req.CheckIfThrowDelayedException ();
2056 public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
2058 if (disposed && closed)
2059 throw new ObjectDisposedException (GetType ().ToString ());
2062 throw new ArgumentNullException ("result");
2064 SocketAsyncResult req = result as SocketAsyncResult;
2066 throw new ArgumentException ("Invalid IAsyncResult", "result");
2068 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2069 throw InvalidAsyncOp ("EndReceiveFrom");
2070 if (!result.IsCompleted)
2071 result.AsyncWaitHandle.WaitOne();
2073 req.CheckIfThrowDelayedException();
2074 end_point = req.EndPoint;
2080 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
2081 ref SocketFlags socketFlags,
2082 ref EndPoint endPoint,
2083 out IPPacketInformation ipPacketInformation)
2085 if (disposed && closed)
2086 throw new ObjectDisposedException (GetType ().ToString ());
2088 if (asyncResult == null)
2089 throw new ArgumentNullException ("asyncResult");
2091 if (endPoint == null)
2092 throw new ArgumentNullException ("endPoint");
2094 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2096 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2098 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2099 throw InvalidAsyncOp ("EndReceiveMessageFrom");
2100 throw new NotImplementedException ();
2104 public int EndSend (IAsyncResult result)
2108 return(EndSend (result, out error));
2116 int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2118 if (disposed && closed)
2119 throw new ObjectDisposedException (GetType ().ToString ());
2121 if (asyncResult == null)
2122 throw new ArgumentNullException ("asyncResult");
2124 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2126 throw new ArgumentException ("Invalid IAsyncResult", "result");
2128 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2129 throw InvalidAsyncOp ("EndSend");
2130 if (!asyncResult.IsCompleted)
2131 asyncResult.AsyncWaitHandle.WaitOne ();
2133 errorCode = req.ErrorCode;
2134 req.CheckIfThrowDelayedException ();
2140 public void EndSendFile (IAsyncResult asyncResult)
2142 if (disposed && closed)
2143 throw new ObjectDisposedException (GetType ().ToString ());
2145 if (asyncResult == null)
2146 throw new ArgumentNullException ("asyncResult");
2148 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
2150 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2152 ares.Delegate.EndInvoke (ares.Original);
2156 Exception InvalidAsyncOp (string method)
2158 return new InvalidOperationException (method + " can only be called once per asynchronous operation");
2161 public int EndSendTo (IAsyncResult result)
2163 if (disposed && closed)
2164 throw new ObjectDisposedException (GetType ().ToString ());
2167 throw new ArgumentNullException ("result");
2169 SocketAsyncResult req = result as SocketAsyncResult;
2171 throw new ArgumentException ("Invalid IAsyncResult", "result");
2173 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
2174 throw InvalidAsyncOp ("EndSendTo");
2175 if (!result.IsCompleted)
2176 result.AsyncWaitHandle.WaitOne();
2178 req.CheckIfThrowDelayedException();
2182 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2183 private extern static void GetSocketOption_arr_internal(IntPtr socket,
2184 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
2187 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2189 if (disposed && closed)
2190 throw new ObjectDisposedException (GetType ().ToString ());
2192 if (optionValue == null)
2193 throw new SocketException ((int) SocketError.Fault,
2194 "Error trying to dereference an invalid pointer");
2198 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
2201 throw new SocketException (error);
2204 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
2206 if (disposed && closed)
2207 throw new ObjectDisposedException (GetType ().ToString ());
2209 byte[] byte_val=new byte[length];
2212 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
2215 throw new SocketException (error);
2220 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
2221 // common options between UNIX and Winsock are FIONREAD,
2222 // FIONBIO and SIOCATMARK. Anything else will depend on the
2224 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2225 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
2226 byte [] output, out int error);
2228 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
2231 throw new ObjectDisposedException (GetType ().ToString ());
2234 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
2238 throw new SocketException (error);
2241 throw new InvalidOperationException ("Must use Blocking property instead.");
2248 public int IOControl (IOControlCode ioControlCode,
2249 byte[] optionInValue,
2250 byte[] optionOutValue)
2252 /* Probably just needs to mirror the int
2253 * overload, but more investigation needed.
2255 throw new NotImplementedException ();
2259 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2260 private extern static void Listen_internal(IntPtr sock, int backlog,
2263 public void Listen (int backlog)
2265 if (disposed && closed)
2266 throw new ObjectDisposedException (GetType ().ToString ());
2269 /* TODO: check if this should be thrown in the
2273 throw new SocketException ((int)SocketError.InvalidArgument);
2278 Listen_internal(socket, backlog, out error);
2281 throw new SocketException (error);
2288 public bool Poll (int time_us, SelectMode mode)
2290 if (disposed && closed)
2291 throw new ObjectDisposedException (GetType ().ToString ());
2293 if (mode != SelectMode.SelectRead &&
2294 mode != SelectMode.SelectWrite &&
2295 mode != SelectMode.SelectError)
2296 throw new NotSupportedException ("'mode' parameter is not valid.");
2299 bool result = Poll_internal (socket, mode, time_us, out error);
2301 throw new SocketException (error);
2303 if (mode == SelectMode.SelectWrite && result && !connected) {
2304 /* Update the connected state; for
2305 * non-blocking Connect()s this is
2306 * when we can find out that the
2307 * connect succeeded.
2309 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
2317 public int Receive (byte [] buffer)
2319 if (disposed && closed)
2320 throw new ObjectDisposedException (GetType ().ToString ());
2323 throw new ArgumentNullException ("buffer");
2327 int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
2329 if (error != SocketError.Success)
2330 throw new SocketException ((int) error);
2335 public int Receive (byte [] buffer, SocketFlags flags)
2337 if (disposed && closed)
2338 throw new ObjectDisposedException (GetType ().ToString ());
2341 throw new ArgumentNullException ("buffer");
2345 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
2347 if (error != SocketError.Success) {
2348 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2349 throw new SocketException ((int) error, "Operation timed out.");
2350 throw new SocketException ((int) error);
2356 public int Receive (byte [] buffer, int size, SocketFlags flags)
2358 if (disposed && closed)
2359 throw new ObjectDisposedException (GetType ().ToString ());
2362 throw new ArgumentNullException ("buffer");
2364 if (size < 0 || size > buffer.Length)
2365 throw new ArgumentOutOfRangeException ("size");
2369 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
2371 if (error != SocketError.Success) {
2372 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2373 throw new SocketException ((int) error, "Operation timed out.");
2374 throw new SocketException ((int) error);
2380 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
2382 if (disposed && closed)
2383 throw new ObjectDisposedException (GetType ().ToString ());
2386 throw new ArgumentNullException ("buffer");
2388 if (offset < 0 || offset > buffer.Length)
2389 throw new ArgumentOutOfRangeException ("offset");
2391 if (size < 0 || offset + size > buffer.Length)
2392 throw new ArgumentOutOfRangeException ("size");
2396 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
2398 if (error != SocketError.Success) {
2399 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2400 throw new SocketException ((int) error, "Operation timed out.");
2401 throw new SocketException ((int) error);
2408 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
2410 if (disposed && closed)
2411 throw new ObjectDisposedException (GetType ().ToString ());
2414 throw new ArgumentNullException ("buffer");
2416 if (offset < 0 || offset > buffer.Length)
2417 throw new ArgumentOutOfRangeException ("offset");
2419 if (size < 0 || offset + size > buffer.Length)
2420 throw new ArgumentOutOfRangeException ("size");
2422 return Receive_nochecks (buffer, offset, size, flags, out error);
2425 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2426 private extern static int Receive_internal (IntPtr sock,
2431 public int Receive (IList<ArraySegment<byte>> buffers)
2436 ret = Receive (buffers, SocketFlags.None, out error);
2437 if (error != SocketError.Success) {
2438 throw new SocketException ((int)error);
2444 [CLSCompliant (false)]
2445 public int Receive (IList<ArraySegment<byte>> buffers,
2446 SocketFlags socketFlags)
2451 ret = Receive (buffers, socketFlags, out error);
2452 if (error != SocketError.Success) {
2453 throw new SocketException ((int)error);
2459 [CLSCompliant (false)]
2460 public int Receive (IList<ArraySegment<byte>> buffers,
2461 SocketFlags socketFlags,
2462 out SocketError errorCode)
2464 if (disposed && closed)
2465 throw new ObjectDisposedException (GetType ().ToString ());
2467 if (buffers == null ||
2468 buffers.Count == 0) {
2469 throw new ArgumentNullException ("buffers");
2472 int numsegments = buffers.Count;
2476 /* Only example I can find of sending a byte
2477 * array reference directly into an internal
2479 * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
2480 * so taking a lead from that...
2482 WSABUF[] bufarray = new WSABUF[numsegments];
2483 GCHandle[] gch = new GCHandle[numsegments];
2485 for(int i = 0; i < numsegments; i++) {
2486 ArraySegment<byte> segment = buffers[i];
2487 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2488 bufarray[i].len = segment.Count;
2489 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2493 ret = Receive_internal (socket, bufarray,
2497 for(int i = 0; i < numsegments; i++) {
2498 if (gch[i].IsAllocated) {
2504 errorCode = (SocketError)nativeError;
2510 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
2512 if (disposed && closed)
2513 throw new ObjectDisposedException (GetType ().ToString ());
2515 // We do not support recv into multiple buffers yet
2516 if (e.BufferList != null)
2517 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
2518 if (e.RemoteEndPoint == null)
2519 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2521 e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
2523 // We always return true for now
2528 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
2530 if (disposed && closed)
2531 throw new ObjectDisposedException (GetType ().ToString ());
2534 throw new ArgumentNullException ("buffer");
2536 if (remoteEP == null)
2537 throw new ArgumentNullException ("remoteEP");
2539 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
2542 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
2544 if (disposed && closed)
2545 throw new ObjectDisposedException (GetType ().ToString ());
2548 throw new ArgumentNullException ("buffer");
2550 if (remoteEP == null)
2551 throw new ArgumentNullException ("remoteEP");
2553 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
2556 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
2557 ref EndPoint remoteEP)
2559 if (disposed && closed)
2560 throw new ObjectDisposedException (GetType ().ToString ());
2563 throw new ArgumentNullException ("buffer");
2565 if (remoteEP == null)
2566 throw new ArgumentNullException ("remoteEP");
2568 if (size < 0 || size > buffer.Length)
2569 throw new ArgumentOutOfRangeException ("size");
2571 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
2574 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2575 private extern static int RecvFrom_internal(IntPtr sock,
2580 ref SocketAddress sockaddr,
2583 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
2584 ref EndPoint remoteEP)
2586 if (disposed && closed)
2587 throw new ObjectDisposedException (GetType ().ToString ());
2590 throw new ArgumentNullException ("buffer");
2592 if (remoteEP == null)
2593 throw new ArgumentNullException ("remoteEP");
2595 if (offset < 0 || offset > buffer.Length)
2596 throw new ArgumentOutOfRangeException ("offset");
2598 if (size < 0 || offset + size > buffer.Length)
2599 throw new ArgumentOutOfRangeException ("size");
2601 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
2604 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
2605 ref EndPoint remote_end)
2608 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
2611 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
2612 ref EndPoint remote_end, bool throwOnError, out int error)
2614 SocketAddress sockaddr = remote_end.Serialize();
2615 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
2616 SocketError err = (SocketError) error;
2618 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2620 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
2622 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
2623 error = (int) SocketError.TimedOut;
2628 throw new SocketException (error);
2638 // If sockaddr is null then we're a connection
2639 // oriented protocol and should ignore the
2640 // remote_end parameter (see MSDN
2641 // documentation for Socket.ReceiveFrom(...) )
2643 if ( sockaddr != null ) {
2644 // Stupidly, EndPoint.Create() is an
2646 remote_end = remote_end.Create (sockaddr);
2649 seed_endpoint = remote_end;
2655 [MonoTODO ("Not implemented")]
2656 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
2658 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2659 if (disposed && closed)
2660 throw new ObjectDisposedException (GetType ().ToString ());
2662 throw new NotImplementedException ();
2665 [MonoTODO ("Not implemented")]
2666 public int ReceiveMessageFrom (byte[] buffer, int offset,
2668 ref SocketFlags socketFlags,
2669 ref EndPoint remoteEP,
2670 out IPPacketInformation ipPacketInformation)
2672 if (disposed && closed)
2673 throw new ObjectDisposedException (GetType ().ToString ());
2676 throw new ArgumentNullException ("buffer");
2678 if (remoteEP == null)
2679 throw new ArgumentNullException ("remoteEP");
2681 if (offset < 0 || offset > buffer.Length)
2682 throw new ArgumentOutOfRangeException ("offset");
2684 if (size < 0 || offset + size > buffer.Length)
2685 throw new ArgumentOutOfRangeException ("size");
2687 /* FIXME: figure out how we get hold of the
2688 * IPPacketInformation
2690 throw new NotImplementedException ();
2693 [MonoTODO ("Not implemented")]
2694 public bool SendPacketsAsync (SocketAsyncEventArgs e)
2696 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2698 if (disposed && closed)
2699 throw new ObjectDisposedException (GetType ().ToString ());
2701 throw new NotImplementedException ();
2706 public int Send (byte [] buf)
2708 if (disposed && closed)
2709 throw new ObjectDisposedException (GetType ().ToString ());
2712 throw new ArgumentNullException ("buf");
2716 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2718 if (error != SocketError.Success)
2719 throw new SocketException ((int) error);
2724 public int Send (byte [] buf, SocketFlags flags)
2726 if (disposed && closed)
2727 throw new ObjectDisposedException (GetType ().ToString ());
2730 throw new ArgumentNullException ("buf");
2734 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
2736 if (error != SocketError.Success)
2737 throw new SocketException ((int) error);
2742 public int Send (byte [] buf, int size, SocketFlags flags)
2744 if (disposed && closed)
2745 throw new ObjectDisposedException (GetType ().ToString ());
2748 throw new ArgumentNullException ("buf");
2750 if (size < 0 || size > buf.Length)
2751 throw new ArgumentOutOfRangeException ("size");
2755 int ret = Send_nochecks (buf, 0, size, flags, out error);
2757 if (error != SocketError.Success)
2758 throw new SocketException ((int) error);
2763 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
2765 if (disposed && closed)
2766 throw new ObjectDisposedException (GetType ().ToString ());
2769 throw new ArgumentNullException ("buffer");
2771 if (offset < 0 || offset > buf.Length)
2772 throw new ArgumentOutOfRangeException ("offset");
2774 if (size < 0 || offset + size > buf.Length)
2775 throw new ArgumentOutOfRangeException ("size");
2779 int ret = Send_nochecks (buf, offset, size, flags, out error);
2781 if (error != SocketError.Success)
2782 throw new SocketException ((int) error);
2788 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2790 if (disposed && closed)
2791 throw new ObjectDisposedException (GetType ().ToString ());
2794 throw new ArgumentNullException ("buffer");
2796 if (offset < 0 || offset > buf.Length)
2797 throw new ArgumentOutOfRangeException ("offset");
2799 if (size < 0 || offset + size > buf.Length)
2800 throw new ArgumentOutOfRangeException ("size");
2802 return Send_nochecks (buf, offset, size, flags, out error);
2805 [MethodImplAttribute (MethodImplOptions.InternalCall)]
2806 private extern static int Send_internal (IntPtr sock,
2811 public int Send (IList<ArraySegment<byte>> buffers)
2816 ret = Send (buffers, SocketFlags.None, out error);
2817 if (error != SocketError.Success) {
2818 throw new SocketException ((int)error);
2824 public int Send (IList<ArraySegment<byte>> buffers,
2825 SocketFlags socketFlags)
2830 ret = Send (buffers, socketFlags, out error);
2831 if (error != SocketError.Success) {
2832 throw new SocketException ((int)error);
2838 [CLSCompliant (false)]
2839 public int Send (IList<ArraySegment<byte>> buffers,
2840 SocketFlags socketFlags,
2841 out SocketError errorCode)
2843 if (disposed && closed) {
2844 throw new ObjectDisposedException (GetType ().ToString ());
2847 if (buffers == null) {
2848 throw new ArgumentNullException ("buffers");
2851 if (buffers.Count == 0) {
2852 throw new ArgumentException ("Buffer is empty", "buffers");
2855 int numsegments = buffers.Count;
2859 WSABUF[] bufarray = new WSABUF[numsegments];
2860 GCHandle[] gch = new GCHandle[numsegments];
2862 for(int i = 0; i < numsegments; i++) {
2863 ArraySegment<byte> segment = buffers[i];
2864 gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
2865 bufarray[i].len = segment.Count;
2866 bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
2870 ret = Send_internal (socket, bufarray,
2874 for(int i = 0; i < numsegments; i++) {
2875 if (gch[i].IsAllocated) {
2881 errorCode = (SocketError)nativeError;
2885 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2886 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
2888 public void SendFile (string fileName)
2890 if (disposed && closed)
2891 throw new ObjectDisposedException (GetType ().ToString ());
2894 throw new NotSupportedException ();
2897 throw new InvalidOperationException ();
2899 SendFile (fileName, null, null, 0);
2902 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
2904 if (disposed && closed)
2905 throw new ObjectDisposedException (GetType ().ToString ());
2908 throw new NotSupportedException ();
2911 throw new InvalidOperationException ();
2913 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
2914 SocketException exc = new SocketException ();
2915 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
2916 throw new FileNotFoundException ();
2921 public bool SendToAsync (SocketAsyncEventArgs e)
2923 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2925 if (disposed && closed)
2926 throw new ObjectDisposedException (GetType ().ToString ());
2927 if (e.RemoteEndPoint == null)
2928 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2930 e.DoOperation (SocketAsyncOperation.SendTo, this);
2932 // We always return true for now
2937 public int SendTo (byte [] buffer, EndPoint remote_end)
2939 if (disposed && closed)
2940 throw new ObjectDisposedException (GetType ().ToString ());
2943 throw new ArgumentNullException ("buffer");
2945 if (remote_end == null)
2946 throw new ArgumentNullException ("remote_end");
2948 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2951 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2953 if (disposed && closed)
2954 throw new ObjectDisposedException (GetType ().ToString ());
2957 throw new ArgumentNullException ("buffer");
2959 if (remote_end == null)
2960 throw new ArgumentNullException ("remote_end");
2962 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2965 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2967 if (disposed && closed)
2968 throw new ObjectDisposedException (GetType ().ToString ());
2971 throw new ArgumentNullException ("buffer");
2973 if (remote_end == null)
2974 throw new ArgumentNullException ("remote_end");
2976 if (size < 0 || size > buffer.Length)
2977 throw new ArgumentOutOfRangeException ("size");
2979 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2982 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2983 private extern static int SendTo_internal(IntPtr sock,
2991 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2992 EndPoint remote_end)
2994 if (disposed && closed)
2995 throw new ObjectDisposedException (GetType ().ToString ());
2998 throw new ArgumentNullException ("buffer");
3000 if (remote_end == null)
3001 throw new ArgumentNullException("remote_end");
3003 if (offset < 0 || offset > buffer.Length)
3004 throw new ArgumentOutOfRangeException ("offset");
3006 if (size < 0 || offset + size > buffer.Length)
3007 throw new ArgumentOutOfRangeException ("size");
3009 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
3012 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
3013 EndPoint remote_end)
3015 SocketAddress sockaddr = remote_end.Serialize ();
3019 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
3021 SocketError err = (SocketError) error;
3023 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
3026 throw new SocketException (error);
3035 seed_endpoint = remote_end;
3040 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
3042 if (disposed && closed)
3043 throw new ObjectDisposedException (GetType ().ToString ());
3045 // I'd throw an ArgumentNullException, but this is what MS does.
3046 if (optionValue == null)
3047 throw new SocketException ((int) SocketError.Fault,
3048 "Error trying to dereference an invalid pointer");
3052 SetSocketOption_internal (socket, optionLevel, optionName, null,
3053 optionValue, 0, out error);
3056 if (error == (int) SocketError.InvalidArgument)
3057 throw new ArgumentException ();
3058 throw new SocketException (error);
3062 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
3064 if (disposed && closed)
3065 throw new ObjectDisposedException (GetType ().ToString ());
3067 // NOTE: if a null is passed, the byte[] overload is used instead...
3068 if (optionValue == null)
3069 throw new ArgumentNullException("optionValue");
3073 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
3074 LingerOption linger = optionValue as LingerOption;
3077 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
3079 throw new ArgumentException ("optionValue");
3081 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
3082 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
3083 MulticastOption multicast = optionValue as MulticastOption;
3084 if (multicast == null)
3086 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
3088 throw new ArgumentException ("optionValue");
3090 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
3091 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
3092 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
3093 if (multicast == null)
3095 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
3097 throw new ArgumentException ("optionValue");
3099 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
3102 throw new ArgumentException ("Invalid value specified.", "optionValue");
3104 throw new ArgumentException ("optionValue");
3109 if (error == (int) SocketError.InvalidArgument)
3110 throw new ArgumentException ();
3111 throw new SocketException (error);
3116 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
3118 if (disposed && closed)
3119 throw new ObjectDisposedException (GetType ().ToString ());
3122 int int_val = (optionValue) ? 1 : 0;
3123 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
3125 if (error == (int) SocketError.InvalidArgument)
3126 throw new ArgumentException ();
3127 throw new SocketException (error);
3133 public override int GetHashCode ()
3136 // The socket is not suitable to serve as a hash code,
3137 // because it will change during its lifetime, but
3138 // this is how MS.NET 1.1 implemented this method.
3139 return (int) socket;