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)
9 // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
10 // http://www.myelin.co.nz
11 // (c) 2004-2006 Novell, Inc. (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Threading;
41 using System.Reflection;
43 using System.Net.Configuration;
47 using System.Collections.Generic;
48 using System.Net.NetworkInformation;
52 namespace System.Net.Sockets
54 public class Socket : IDisposable
56 enum SocketOperation {
71 [StructLayout (LayoutKind.Sequential)]
72 private sealed class SocketAsyncResult: IAsyncResult
74 /* Same structure in the runtime */
78 AsyncCallback callback;
79 WaitHandle waithandle;
81 Exception delayedException;
83 public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
84 public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
85 public int Offset; // Receive,ReceiveFrom,Send,SendTo
86 public int Size; // Receive,ReceiveFrom,Send,SendTo
87 public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
88 public Socket AcceptSocket; // AcceptReceive
89 public IPAddress[] Addresses; // Connect
90 public int Port; // Connect
92 public IList<ArraySegment<byte>> Buffers; // Receive, Send
94 public object Buffers; // Reserve this slot in older profiles
96 public bool ReuseSocket; // Disconnect
104 public bool blocking;
106 SocketOperation operation;
109 public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
112 this.blocking = sock.blocking;
113 this.handle = sock.socket;
115 this.callback = callback;
116 this.operation = operation;
117 SockFlags = SocketFlags.None;
120 public void CheckIfThrowDelayedException ()
122 if (delayedException != null) {
123 throw delayedException;
127 throw new SocketException (error);
131 void CompleteAllOnDispose (Queue queue)
133 object [] pending = queue.ToArray ();
137 for (int i = 0; i < pending.Length; i++) {
138 SocketAsyncResult ares = (SocketAsyncResult) pending [i];
139 cb = new WaitCallback (ares.CompleteDisposed);
140 ThreadPool.QueueUserWorkItem (cb, null);
144 void CompleteDisposed (object unused)
149 public void Complete ()
151 if (operation != SocketOperation.Receive && Sock.disposed)
152 delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
157 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
159 } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
164 SocketAsyncCall sac = null;
165 SocketAsyncResult req = null;
167 queue.Dequeue (); // remove ourselves
168 if (queue.Count > 0) {
169 req = (SocketAsyncResult) queue.Peek ();
170 if (!Sock.disposed) {
171 Worker worker = new Worker (req);
172 sac = GetDelegate (worker, req.operation);
174 CompleteAllOnDispose (queue);
180 sac.BeginInvoke (null, req);
183 if (callback != null)
187 SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
190 case SocketOperation.Receive:
191 return new SocketAsyncCall (worker.Receive);
192 case SocketOperation.ReceiveFrom:
193 return new SocketAsyncCall (worker.ReceiveFrom);
194 case SocketOperation.Send:
195 return new SocketAsyncCall (worker.Send);
196 case SocketOperation.SendTo:
197 return new SocketAsyncCall (worker.SendTo);
199 return null; // never happens
203 public void Complete (bool synch)
205 completed_sync = synch;
209 public void Complete (int total)
215 public void Complete (Exception e, bool synch)
217 completed_sync = synch;
218 delayedException = e;
222 public void Complete (Exception e)
224 delayedException = e;
228 public void Complete (Socket s)
234 public void Complete (Socket s, int total)
241 public object AsyncState {
247 public WaitHandle AsyncWaitHandle {
250 if (waithandle == null)
251 waithandle = new ManualResetEvent (completed);
261 public bool CompletedSynchronously {
263 return(completed_sync);
267 public bool IsCompleted {
274 if (waithandle != null && value) {
275 ((ManualResetEvent) waithandle).Set ();
281 public Socket Socket {
288 get { return total; }
289 set { total = value; }
292 public SocketError ErrorCode
296 SocketException ex = delayedException as SocketException;
299 return(ex.SocketErrorCode);
302 return((SocketError)error);
305 return(SocketError.Success);
310 private sealed class Worker
312 SocketAsyncResult result;
314 public Worker (SocketAsyncResult ares)
319 public void Accept ()
321 Socket acc_socket = null;
323 acc_socket = result.Sock.Accept ();
324 } catch (Exception e) {
329 result.Complete (acc_socket);
332 /* only used in 2.0 profile and newer, but
333 * leave in older profiles to keep interface
334 * to runtime consistent
336 public void AcceptReceive ()
338 Socket acc_socket = null;
341 if (result.AcceptSocket == null) {
342 acc_socket = result.Sock.Accept ();
344 acc_socket = result.AcceptSocket;
345 result.Sock.Accept (acc_socket);
347 } catch (Exception e) {
356 total = acc_socket.Receive_nochecks (result.Buffer,
361 } catch (Exception e) {
366 result.Complete (acc_socket, total);
369 public void Connect ()
371 /* If result.EndPoint is non-null,
372 * this is the standard one-address
373 * connect attempt. Otherwise
374 * Addresses must be non-null and
375 * contain a list of addresses to try
376 * to connect to; the first one to
377 * succeed causes the rest of the list
380 if (result.EndPoint != null) {
382 if (!result.Sock.Blocking) {
384 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
386 result.Sock.connected = true;
388 result.Complete (new SocketException (success));
392 result.Sock.Connect (result.EndPoint);
393 result.Sock.connected = true;
395 } catch (Exception e) {
401 } else if (result.Addresses != null) {
402 foreach(IPAddress address in result.Addresses) {
403 IPEndPoint iep = new IPEndPoint (address, result.Port);
404 SocketAddress serial = iep.Serialize ();
407 Socket.Connect_internal (result.Sock.socket, serial, out error);
409 result.Sock.connected = true;
412 } else if (error != (int)SocketError.InProgress &&
413 error != (int)SocketError.WouldBlock) {
417 if (!result.Sock.Blocking) {
419 result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
421 result.Sock.connected = true;
428 result.Complete (new SocketException ((int)SocketError.InProgress));
430 result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
434 /* Also only used in 2.0 profile and newer */
435 public void Disconnect ()
439 result.Sock.Disconnect (result.ReuseSocket);
440 } catch (Exception e) {
446 result.Complete (new SocketException ((int)SocketError.Fault));
450 public void Receive ()
452 // Actual recv() done in the runtime
456 public void ReceiveFrom ()
460 total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
464 ref result.EndPoint);
465 } catch (Exception e) {
470 result.Complete (total);
475 void UpdateSendValues (int last_sent)
477 if (result.error == 0) {
478 send_so_far += last_sent;
479 result.Offset += last_sent;
480 result.Size -= last_sent;
486 // Actual send() done in the runtime
487 if (result.error == 0) {
488 UpdateSendValues (result.Total);
489 if (result.Sock.disposed) {
494 if (result.Size > 0) {
495 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
496 sac.BeginInvoke (null, result);
497 return; // Have to finish writing everything. See bug #74475.
499 result.Total = send_so_far;
504 public void SendTo ()
508 total = result.Sock.SendTo_nochecks (result.Buffer,
514 UpdateSendValues (total);
515 if (result.Size > 0) {
516 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
517 sac.BeginInvoke (null, result);
518 return; // Have to finish writing everything. See bug #74475.
520 result.Total = send_so_far;
521 } catch (Exception e) {
530 /* the field "socket" is looked up by name by the runtime */
531 private IntPtr socket;
532 private AddressFamily address_family;
533 private SocketType socket_type;
534 private ProtocolType protocol_type;
535 internal bool blocking=true;
536 private Queue readQ = new Queue (2);
537 private Queue writeQ = new Queue (2);
539 delegate void SocketAsyncCall ();
541 * These two fields are looked up by name by the runtime, don't change
542 * their name without also updating the runtime code.
544 private static int ipv4Supported = -1, ipv6Supported = -1;
546 /* When true, the socket was connected at the time of
547 * the last IO operation
549 private bool connected=false;
550 /* true if we called Close_internal */
552 internal bool disposed;
555 /* Used in LocalEndPoint and RemoteEndPoint if the
556 * Mono.Posix assembly is available
558 private static object unixendpoint=null;
559 private static Type unixendpointtype=null;
562 private bool isbound = false;
563 private bool islistening = false;
564 private bool useoverlappedIO = false;
568 static void AddSockets (ArrayList sockets, IList list, string name)
571 foreach (Socket sock in list) {
572 if (sock == null) // MS throws a NullRef
573 throw new ArgumentNullException ("name", "Contains a null element");
581 [MethodImplAttribute(MethodImplOptions.InternalCall)]
582 private extern static void Select_internal (ref Socket [] sockets,
586 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
588 ArrayList list = new ArrayList ();
589 AddSockets (list, checkRead, "checkRead");
590 AddSockets (list, checkWrite, "checkWrite");
591 AddSockets (list, checkError, "checkError");
593 if (list.Count == 3) {
594 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
595 "All the lists are null or empty.");
600 * The 'sockets' array contains: READ socket 0-n, null,
601 * WRITE socket 0-n, null,
602 * ERROR socket 0-n, null
604 Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
605 Select_internal (ref sockets, microSeconds, out error);
608 throw new SocketException (error);
610 if (checkRead != null)
613 if (checkWrite != null)
616 if (checkError != null)
623 int count = sockets.Length;
624 IList currentList = checkRead;
625 for (int i = 0; i < count; i++) {
626 Socket sock = sockets [i];
627 if (sock == null) { // separator
628 currentList = (mode == 0) ? checkWrite : checkError;
633 if (currentList != null) {
634 if (currentList == checkWrite &&
635 sock.connected == false) {
636 if ((int)sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
637 sock.connected = true;
641 currentList.Add (sock);
650 ass = Assembly.Load (Consts.AssemblyMono_Posix);
651 } catch (FileNotFoundException) {
655 unixendpointtype=ass.GetType("Mono.Posix.UnixEndPoint");
657 /* The endpoint Create() method is an instance
660 Type[] arg_types=new Type[1];
661 arg_types[0]=typeof(string);
662 ConstructorInfo cons=unixendpointtype.GetConstructor(arg_types);
664 object[] args=new object[1];
667 unixendpoint=cons.Invoke(args);
670 // private constructor used by Accept, which already
671 // has a socket handle to use
672 private Socket(AddressFamily family, SocketType type,
673 ProtocolType proto, IntPtr sock) {
674 address_family=family;
682 // Creates a new system socket, returning the handle
683 [MethodImplAttribute(MethodImplOptions.InternalCall)]
684 private extern IntPtr Socket_internal(AddressFamily family,
689 private void SocketDefaults ()
693 if (address_family == AddressFamily.InterNetwork ||
694 address_family == AddressFamily.InterNetworkV6) {
695 /* This is the default, but it
696 * probably has nasty side
697 * effects on Linux, as the
698 * socket option is kludged by
699 * turning on or off PMTU
702 this.DontFragment = false;
705 /* Set the same defaults as the MS runtime */
706 this.ReceiveBufferSize = 8192;
707 this.SendBufferSize = 8192;
708 } catch (SocketException) {
713 public Socket(AddressFamily family, SocketType type,
714 ProtocolType proto) {
715 address_family=family;
721 socket=Socket_internal(family, type, proto, out error);
723 throw new SocketException (error);
730 public Socket (SocketInformation socketInformation)
732 throw new NotImplementedException ("SocketInformation not figured out yet");
734 //address_family = socketInformation.address_family;
735 //socket_type = socketInformation.socket_type;
736 //protocol_type = socketInformation.protocol_type;
737 address_family = AddressFamily.InterNetwork;
738 socket_type = SocketType.Stream;
739 protocol_type = ProtocolType.IP;
742 socket = Socket_internal (address_family, socket_type, protocol_type, out error);
744 throw new SocketException (error);
751 public AddressFamily AddressFamily {
753 return(address_family);
757 // Returns the amount of data waiting to be read on socket
758 [MethodImplAttribute(MethodImplOptions.InternalCall)]
759 private extern static int Available_internal(IntPtr socket,
763 public int Available {
765 if (disposed && closed)
766 throw new ObjectDisposedException (GetType ().ToString ());
770 ret = Available_internal(socket, out error);
773 throw new SocketException (error);
780 [MethodImplAttribute(MethodImplOptions.InternalCall)]
781 private extern static void Blocking_internal(IntPtr socket,
785 public bool Blocking {
790 if (disposed && closed)
791 throw new ObjectDisposedException (GetType ().ToString ());
795 Blocking_internal(socket, value, out error);
798 throw new SocketException (error);
805 public bool Connected {
812 public bool DontFragment
815 if (disposed && closed) {
816 throw new ObjectDisposedException (GetType ().ToString ());
821 if (address_family == AddressFamily.InterNetwork) {
822 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
823 } else if (address_family == AddressFamily.InterNetworkV6) {
824 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
826 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
829 return(dontfragment);
832 if (disposed && closed) {
833 throw new ObjectDisposedException (GetType ().ToString ());
836 if (address_family == AddressFamily.InterNetwork) {
837 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
838 } else if (address_family == AddressFamily.InterNetworkV6) {
839 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
841 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
846 public bool EnableBroadcast
849 if (disposed && closed) {
850 throw new ObjectDisposedException (GetType ().ToString ());
853 if (protocol_type != ProtocolType.Udp) {
854 throw new SocketException ((int)SocketError.ProtocolOption);
857 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
860 if (disposed && closed) {
861 throw new ObjectDisposedException (GetType ().ToString ());
864 if (protocol_type != ProtocolType.Udp) {
865 throw new SocketException ((int)SocketError.ProtocolOption);
868 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
872 public bool ExclusiveAddressUse
875 if (disposed && closed) {
876 throw new ObjectDisposedException (GetType ().ToString ());
879 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
882 if (disposed && closed) {
883 throw new ObjectDisposedException (GetType ().ToString ());
886 throw new InvalidOperationException ("Bind has already been called for this socket");
889 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
900 public LingerOption LingerState
903 if (disposed && closed) {
904 throw new ObjectDisposedException (GetType ().ToString ());
907 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
910 if (disposed && closed) {
911 throw new ObjectDisposedException (GetType ().ToString ());
914 SetSocketOption (SocketOptionLevel.Socket,
915 SocketOptionName.Linger,
920 public bool 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 bool multicastloopback;
943 if (address_family == AddressFamily.InterNetwork) {
944 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
945 } else if (address_family == AddressFamily.InterNetworkV6) {
946 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
948 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
951 return(multicastloopback);
954 if (disposed && closed) {
955 throw new ObjectDisposedException (GetType ().ToString ());
958 /* Even though this option can be set
959 * for TCP sockets on Linux, throw
960 * this exception anyway to be
961 * compatible (the MSDN docs say
962 * "Setting this property on a
963 * Transmission Control Protocol (TCP)
964 * socket will have no effect." but
965 * the MS runtime throws the
968 if (protocol_type == ProtocolType.Tcp) {
969 throw new SocketException ((int)SocketError.ProtocolOption);
972 if (address_family == AddressFamily.InterNetwork) {
973 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
974 } else if (address_family == AddressFamily.InterNetworkV6) {
975 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
977 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
982 public static bool OSSupportsIPv6
985 NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces ();
987 foreach(NetworkInterface adapter in nics) {
988 if (adapter.Supports (NetworkInterfaceComponent.IPv6) == true) {
998 public int ReceiveBufferSize
1001 if (disposed && closed) {
1002 throw new ObjectDisposedException (GetType ().ToString ());
1004 return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer));
1007 if (disposed && closed) {
1008 throw new ObjectDisposedException (GetType ().ToString ());
1011 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
1014 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, value);
1018 public int SendBufferSize
1021 if (disposed && closed) {
1022 throw new ObjectDisposedException (GetType ().ToString ());
1024 return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendBuffer));
1027 if (disposed && closed) {
1028 throw new ObjectDisposedException (GetType ().ToString ());
1031 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
1034 SetSocketOption (SocketOptionLevel.Socket,
1035 SocketOptionName.SendBuffer,
1043 if (disposed && closed) {
1044 throw new ObjectDisposedException (GetType ().ToString ());
1049 if (address_family == AddressFamily.InterNetwork) {
1050 ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive));
1051 } else if (address_family == AddressFamily.InterNetworkV6) {
1052 ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit));
1054 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
1060 if (disposed && closed) {
1061 throw new ObjectDisposedException (GetType ().ToString ());
1064 if (address_family == AddressFamily.InterNetwork) {
1065 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, value);
1066 } else if (address_family == AddressFamily.InterNetworkV6) {
1067 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit, value);
1069 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
1074 /* This doesn't do anything on Mono yet */
1075 public bool UseOnlyOverlappedIO
1078 return(useoverlappedIO);
1081 useoverlappedIO = value;
1086 public IntPtr Handle {
1092 Exception GetNotImplemented (string msg)
1094 return new NotImplementedException (msg);
1098 // Returns the local endpoint details in addr and port
1099 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1100 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
1102 // Wish: support non-IP endpoints.
1103 public EndPoint LocalEndPoint {
1105 if (disposed && closed)
1106 throw new ObjectDisposedException (GetType ().ToString ());
1111 sa=LocalEndPoint_internal(socket, out error);
1114 throw new SocketException (error);
1117 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6) {
1118 // Stupidly, EndPoint.Create() is an
1120 return new IPEndPoint(0, 0).Create(sa);
1121 } else if (sa.Family==AddressFamily.Unix && unixendpoint!=null) {
1122 return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
1124 throw GetNotImplemented (Locale.GetText ("No support for the {0} AddressFamily", sa.Family));
1129 public ProtocolType ProtocolType {
1131 return(protocol_type);
1135 // Returns the remote endpoint details in addr and port
1136 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1137 private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
1140 // Wish: Support non-IP endpoints
1142 public EndPoint RemoteEndPoint {
1144 if (disposed && closed)
1145 throw new ObjectDisposedException (GetType ().ToString ());
1150 sa=RemoteEndPoint_internal(socket, out error);
1153 throw new SocketException (error);
1156 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6 ) {
1157 // Stupidly, EndPoint.Create() is an
1159 return new IPEndPoint(0, 0).Create(sa);
1160 } else if (sa.Family==AddressFamily.Unix &&
1161 unixendpoint!=null) {
1162 return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
1164 throw new NotSupportedException(Locale.GetText ("the {0} address family is not supported in Mono", sa.Family));
1169 public SocketType SocketType {
1171 return(socket_type);
1175 public static bool SupportsIPv4 {
1177 CheckProtocolSupport();
1178 return ipv4Supported == 1;
1182 public static bool SupportsIPv6 {
1184 CheckProtocolSupport();
1185 return ipv6Supported == 1;
1190 public int SendTimeout {
1192 if (disposed && closed) {
1193 throw new ObjectDisposedException (GetType ().ToString ());
1196 return (int)GetSocketOption(
1197 SocketOptionLevel.Socket,
1198 SocketOptionName.SendTimeout);
1201 if (disposed && closed) {
1202 throw new ObjectDisposedException (GetType ().ToString ());
1205 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1208 /* According to the MSDN docs we
1209 * should adjust values between 1 and
1210 * 499 to 500, but the MS runtime
1218 SocketOptionLevel.Socket,
1219 SocketOptionName.SendTimeout, value);
1223 public int ReceiveTimeout {
1225 if (disposed && closed) {
1226 throw new ObjectDisposedException (GetType ().ToString ());
1229 return (int)GetSocketOption(
1230 SocketOptionLevel.Socket,
1231 SocketOptionName.ReceiveTimeout);
1234 if (disposed && closed) {
1235 throw new ObjectDisposedException (GetType ().ToString ());
1238 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
1246 SocketOptionLevel.Socket,
1247 SocketOptionName.ReceiveTimeout, value);
1251 public bool NoDelay {
1253 if (disposed && closed) {
1254 throw new ObjectDisposedException (GetType ().ToString ());
1257 if (protocol_type == ProtocolType.Udp) {
1258 throw new SocketException ((int)SocketError.ProtocolOption);
1261 return (int)(GetSocketOption (
1262 SocketOptionLevel.Tcp,
1263 SocketOptionName.NoDelay)) != 0;
1267 if (disposed && closed) {
1268 throw new ObjectDisposedException (GetType ().ToString ());
1271 if (protocol_type == ProtocolType.Udp) {
1272 throw new SocketException ((int)SocketError.ProtocolOption);
1276 SocketOptionLevel.Tcp,
1277 SocketOptionName.NoDelay, value ? 1 : 0);
1282 internal static void CheckProtocolSupport()
1284 if(ipv4Supported == -1) {
1286 Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1296 if(ipv6Supported == -1) {
1297 #if NET_2_0 && CONFIGURATION_DEP
1298 SettingsSection config;
1299 config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
1301 ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
1303 NetConfig config = (NetConfig)System.Configuration.ConfigurationSettings.GetConfig("system.net/settings");
1306 ipv6Supported = config.ipv6Enabled?-1:0;
1308 if(ipv6Supported != 0) {
1310 Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
1320 // Creates a new system socket, returning the handle
1321 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1322 private extern static IntPtr Accept_internal(IntPtr sock,
1325 Thread blocking_thread;
1326 public Socket Accept() {
1327 if (disposed && closed)
1328 throw new ObjectDisposedException (GetType ().ToString ());
1331 IntPtr sock = (IntPtr) (-1);
1332 blocking_thread = Thread.CurrentThread;
1334 sock = Accept_internal(socket, out error);
1335 } catch (ThreadAbortException) {
1337 Thread.ResetAbort ();
1338 error = (int) SocketError.Interrupted;
1341 blocking_thread = null;
1345 throw new SocketException (error);
1348 Socket accepted = new Socket(this.AddressFamily,
1350 this.ProtocolType, sock);
1352 accepted.Blocking = this.Blocking;
1356 private void Accept (Socket acceptSocket)
1358 if (disposed && closed) {
1359 throw new ObjectDisposedException (GetType ().ToString ());
1363 IntPtr sock = (IntPtr)(-1);
1364 blocking_thread = Thread.CurrentThread;
1367 sock = Accept_internal (socket, out error);
1368 } catch (ThreadAbortException) {
1370 Thread.ResetAbort ();
1371 error = (int)SocketError.Interrupted;
1374 blocking_thread = null;
1378 throw new SocketException (error);
1381 acceptSocket.address_family = this.AddressFamily;
1382 acceptSocket.socket_type = this.SocketType;
1383 acceptSocket.protocol_type = this.ProtocolType;
1384 acceptSocket.socket = sock;
1385 acceptSocket.connected = true;
1386 acceptSocket.Blocking = this.Blocking;
1388 /* FIXME: figure out what if anything else
1393 public IAsyncResult BeginAccept(AsyncCallback callback,
1397 if (disposed && closed)
1398 throw new ObjectDisposedException (GetType ().ToString ());
1401 /* FIXME: check the 1.1 docs for this too */
1402 if (!isbound || !islistening) {
1403 throw new InvalidOperationException ();
1407 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1408 Worker worker = new Worker (req);
1409 SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1410 sac.BeginInvoke (null, req);
1415 public IAsyncResult BeginAccept (int receiveSize,
1416 AsyncCallback callback,
1419 if (disposed && closed) {
1420 throw new ObjectDisposedException (GetType ().ToString ());
1422 if (receiveSize < 0) {
1423 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1426 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1427 Worker worker = new Worker (req);
1428 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1430 req.Buffer = new byte[receiveSize];
1432 req.Size = receiveSize;
1433 req.SockFlags = SocketFlags.None;
1435 sac.BeginInvoke (null, req);
1439 public IAsyncResult BeginAccept (Socket acceptSocket,
1441 AsyncCallback callback,
1444 if (disposed && closed) {
1445 throw new ObjectDisposedException (GetType ().ToString ());
1447 if (receiveSize < 0) {
1448 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
1450 if (acceptSocket != null) {
1451 if (acceptSocket.disposed && acceptSocket.closed) {
1452 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
1455 if (acceptSocket.IsBound) {
1456 throw new InvalidOperationException ();
1459 /* For some reason the MS runtime
1460 * barfs if the new socket is not TCP,
1461 * even though it's just about to blow
1462 * away all those parameters
1464 if (acceptSocket.ProtocolType != ProtocolType.Tcp) {
1465 throw new SocketException ((int)SocketError.InvalidArgument);
1469 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
1470 Worker worker = new Worker (req);
1471 SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
1473 req.Buffer = new byte[receiveSize];
1475 req.Size = receiveSize;
1476 req.SockFlags = SocketFlags.None;
1477 req.AcceptSocket = acceptSocket;
1479 sac.BeginInvoke (null, req);
1484 public IAsyncResult BeginConnect(EndPoint end_point,
1485 AsyncCallback callback,
1488 if (disposed && closed)
1489 throw new ObjectDisposedException (GetType ().ToString ());
1491 if (end_point == null)
1492 throw new ArgumentNullException ("end_point");
1494 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1495 req.EndPoint = end_point;
1497 // Bug #75154: Connect() should not succeed for .Any addresses.
1498 if (end_point is IPEndPoint) {
1499 IPEndPoint ep = (IPEndPoint) end_point;
1500 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
1501 req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
1508 SocketAddress serial = end_point.Serialize ();
1509 Connect_internal (socket, serial, out error);
1513 req.Complete (true);
1514 } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
1517 req.Complete (new SocketException (error), true);
1521 if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
1524 Worker worker = new Worker (req);
1525 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1526 sac.BeginInvoke (null, req);
1533 public IAsyncResult BeginConnect (IPAddress address, int port,
1534 AsyncCallback callback,
1537 if (disposed && closed) {
1538 throw new ObjectDisposedException (GetType ().ToString ());
1540 if (address == null) {
1541 throw new ArgumentNullException ("address");
1543 if (address.ToString ().Length == 0) {
1544 throw new ArgumentException ("The length of the IP address is zero");
1547 throw new InvalidOperationException ();
1550 IPEndPoint iep = new IPEndPoint (address, port);
1551 return(BeginConnect (iep, callback, state));
1554 public IAsyncResult BeginConnect (IPAddress[] addresses,
1556 AsyncCallback callback,
1559 if (disposed && closed) {
1560 throw new ObjectDisposedException (GetType ().ToString ());
1562 if (addresses == null) {
1563 throw new ArgumentNullException ("addresses");
1565 if (this.AddressFamily != AddressFamily.InterNetwork &&
1566 this.AddressFamily != AddressFamily.InterNetworkV6) {
1567 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1570 throw new InvalidOperationException ();
1573 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1574 req.Addresses = addresses;
1578 Worker worker = new Worker (req);
1579 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1580 sac.BeginInvoke (null, req);
1585 public IAsyncResult BeginConnect (string host, int port,
1586 AsyncCallback callback,
1589 if (disposed && closed) {
1590 throw new ObjectDisposedException (GetType ().ToString ());
1593 throw new ArgumentNullException ("host");
1595 if (address_family != AddressFamily.InterNetwork &&
1596 address_family != AddressFamily.InterNetworkV6) {
1597 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
1600 throw new InvalidOperationException ();
1603 IPHostEntry hostent = Dns.GetHostEntry (host);
1604 return(BeginConnect (hostent.AddressList, port,
1608 public IAsyncResult BeginDisconnect (bool reuseSocket,
1609 AsyncCallback callback,
1612 if (disposed && closed) {
1613 throw new ObjectDisposedException (GetType ().ToString ());
1616 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
1617 req.ReuseSocket = reuseSocket;
1619 Worker worker = new Worker (req);
1620 SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
1621 sac.BeginInvoke (null, req);
1627 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1629 SocketFlags socket_flags,
1630 AsyncCallback callback,
1633 if (disposed && closed)
1634 throw new ObjectDisposedException (GetType ().ToString ());
1637 throw new ArgumentNullException ("buffer");
1639 if (offset < 0 || offset > buffer.Length)
1640 throw new ArgumentOutOfRangeException ("offset");
1642 if (size < 0 || offset + size > buffer.Length)
1643 throw new ArgumentOutOfRangeException ("size");
1645 SocketAsyncResult req;
1647 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1648 req.Buffer = buffer;
1649 req.Offset = offset;
1651 req.SockFlags = socket_flags;
1652 readQ.Enqueue (req);
1653 if (readQ.Count == 1) {
1654 Worker worker = new Worker (req);
1655 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1656 sac.BeginInvoke (null, req);
1663 public IAsyncResult BeginReceive (byte[] buffer, int offset,
1664 int size, SocketFlags flags,
1665 out SocketError error,
1666 AsyncCallback callback,
1669 /* As far as I can tell from the docs and from
1670 * experimentation, a pointer to the
1671 * SocketError parameter is not supposed to be
1672 * saved for the async parts. And as we don't
1673 * set any socket errors in the setup code, we
1674 * just have to set it to Success.
1676 error = SocketError.Success;
1677 return(BeginReceive (buffer, offset, size, flags,
1681 [CLSCompliant (false)]
1682 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1683 SocketFlags socketFlags,
1684 AsyncCallback callback,
1687 if (disposed && closed) {
1688 throw new ObjectDisposedException (GetType ().ToString ());
1690 if (buffers == null) {
1691 throw new ArgumentNullException ("buffers");
1694 SocketAsyncResult req;
1696 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1697 req.Buffers = buffers;
1698 req.SockFlags = socketFlags;
1699 readQ.Enqueue (req);
1700 if (readQ.Count == 1) {
1701 Worker worker = new Worker (req);
1702 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1703 sac.BeginInvoke (null, req);
1710 [CLSCompliant (false)]
1711 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
1712 SocketFlags socketFlags,
1713 out SocketError errorCode,
1714 AsyncCallback callback,
1717 /* I assume the same SocketError semantics as
1720 errorCode = SocketError.Success;
1721 return(BeginReceive (buffers, socketFlags, callback,
1726 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1728 SocketFlags socket_flags,
1729 ref EndPoint remote_end,
1730 AsyncCallback callback,
1732 if (disposed && closed)
1733 throw new ObjectDisposedException (GetType ().ToString ());
1736 throw new ArgumentNullException ("buffer");
1739 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1742 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1744 if (offset + size > buffer.Length)
1745 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1747 SocketAsyncResult req;
1749 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1750 req.Buffer = buffer;
1751 req.Offset = offset;
1753 req.SockFlags = socket_flags;
1754 req.EndPoint = remote_end;
1755 readQ.Enqueue (req);
1756 if (readQ.Count == 1) {
1757 Worker worker = new Worker (req);
1758 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1759 sac.BeginInvoke (null, req);
1765 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1766 AsyncCallback callback, object state)
1768 if (disposed && closed)
1769 throw new ObjectDisposedException (GetType ().ToString ());
1772 throw new ArgumentNullException ("buffer");
1775 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1778 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1780 if (offset + size > buffer.Length)
1781 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1784 /* TODO: Check this exception in the 1.1 profile */
1785 if (connected == false) {
1786 throw new SocketException ((int)SocketError.NotConnected);
1790 SocketAsyncResult req;
1792 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1793 req.Buffer = buffer;
1794 req.Offset = offset;
1796 req.SockFlags = socket_flags;
1797 writeQ.Enqueue (req);
1798 if (writeQ.Count == 1) {
1799 Worker worker = new Worker (req);
1800 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1801 sac.BeginInvoke (null, req);
1808 public IAsyncResult BeginSend (byte[] buffer, int offset,
1810 SocketFlags socketFlags,
1811 out SocketError errorCode,
1812 AsyncCallback callback,
1815 if (connected == false) {
1816 errorCode = SocketError.NotConnected;
1817 throw new SocketException ((int)errorCode);
1820 errorCode = SocketError.Success;
1822 return(BeginSend (buffer, offset, size, socketFlags,
1826 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1827 SocketFlags socketFlags,
1828 AsyncCallback callback,
1831 if (disposed && closed) {
1832 throw new ObjectDisposedException (GetType ().ToString ());
1834 if (buffers == null) {
1835 throw new ArgumentNullException ("buffers");
1838 if (connected == false) {
1839 throw new SocketException ((int)SocketError.NotConnected);
1842 SocketAsyncResult req;
1844 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1845 req.Buffers = buffers;
1846 req.SockFlags = socketFlags;
1847 writeQ.Enqueue (req);
1848 if (writeQ.Count == 1) {
1849 Worker worker = new Worker (req);
1850 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1851 sac.BeginInvoke (null, req);
1858 [CLSCompliant (false)]
1859 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
1860 SocketFlags socketFlags,
1861 out SocketError errorCode,
1862 AsyncCallback callback,
1865 if (connected == false) {
1866 errorCode = SocketError.NotConnected;
1867 throw new SocketException ((int)errorCode);
1870 errorCode = SocketError.Success;
1871 return(BeginSend (buffers, socketFlags, callback,
1876 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1878 SocketFlags socket_flags,
1879 EndPoint remote_end,
1880 AsyncCallback callback,
1882 if (disposed && closed)
1883 throw new ObjectDisposedException (GetType ().ToString ());
1886 throw new ArgumentNullException ("buffer");
1889 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
1892 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
1894 if (offset + size > buffer.Length)
1895 throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
1897 SocketAsyncResult req;
1899 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1900 req.Buffer = buffer;
1901 req.Offset = offset;
1903 req.SockFlags = socket_flags;
1904 req.EndPoint = remote_end;
1905 writeQ.Enqueue (req);
1906 if (writeQ.Count == 1) {
1907 Worker worker = new Worker (req);
1908 SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1909 sac.BeginInvoke (null, req);
1915 // Creates a new system socket, returning the handle
1916 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1917 private extern static void Bind_internal(IntPtr sock,
1921 public void Bind(EndPoint local_end) {
1922 if (disposed && closed)
1923 throw new ObjectDisposedException (GetType ().ToString ());
1925 if(local_end==null) {
1926 throw new ArgumentNullException("local_end");
1931 Bind_internal(socket, local_end.Serialize(),
1934 throw new SocketException (error);
1943 // Closes the socket
1944 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1945 private extern static void Close_internal(IntPtr socket,
1948 public void Close() {
1949 ((IDisposable) this).Dispose ();
1953 public void Close (int timeout)
1955 System.Timers.Timer close_timer = new System.Timers.Timer ();
1956 close_timer.Elapsed += new ElapsedEventHandler (OnTimeoutClose);
1957 close_timer.Interval = timeout * 1000;
1958 close_timer.AutoReset = false;
1959 close_timer.Enabled = true;
1962 private void OnTimeoutClose (object source, ElapsedEventArgs e)
1968 // Connects to the remote address
1969 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1970 private extern static void Connect_internal(IntPtr sock,
1974 public void Connect(EndPoint remote_end) {
1975 if (disposed && closed)
1976 throw new ObjectDisposedException (GetType ().ToString ());
1978 if(remote_end==null) {
1979 throw new ArgumentNullException("remote_end");
1982 if (remote_end is IPEndPoint) {
1983 IPEndPoint ep = (IPEndPoint) remote_end;
1984 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
1985 throw new SocketException ((int) SocketError.AddressNotAvailable);
1989 /* TODO: check this for the 1.1 profile too */
1991 throw new InvalidOperationException ();
1995 SocketAddress serial = remote_end.Serialize ();
1998 blocking_thread = Thread.CurrentThread;
2000 Connect_internal (socket, serial, out error);
2001 } catch (ThreadAbortException) {
2003 Thread.ResetAbort ();
2004 error = (int) SocketError.Interrupted;
2007 blocking_thread = null;
2011 throw new SocketException (error);
2022 public void Connect (IPAddress address, int port)
2024 Connect (new IPEndPoint (address, port));
2027 public void Connect (IPAddress[] addresses, int port)
2029 if (disposed && closed) {
2030 throw new ObjectDisposedException (GetType ().ToString ());
2032 if (addresses == null) {
2033 throw new ArgumentNullException ("addresses");
2035 if (this.AddressFamily != AddressFamily.InterNetwork &&
2036 this.AddressFamily != AddressFamily.InterNetworkV6) {
2037 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
2040 throw new InvalidOperationException ();
2043 /* FIXME: do non-blocking sockets Poll here? */
2044 foreach(IPAddress address in addresses) {
2045 IPEndPoint iep = new IPEndPoint (address,
2047 SocketAddress serial = iep.Serialize ();
2050 Connect_internal (socket, serial, out error);
2054 } else if (error != (int)SocketError.InProgress &&
2055 error != (int)SocketError.WouldBlock) {
2060 Poll (-1, SelectMode.SelectWrite);
2061 int success = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
2070 public void Connect (string host, int port)
2072 IPHostEntry hostent = Dns.GetHostEntry (host);
2073 Connect (hostent.AddressList, port);
2076 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2077 private extern static void Disconnect_internal(IntPtr sock,
2081 /* According to the docs, the MS runtime will throw
2082 * PlatformNotSupportedException if the platform is
2083 * newer than w2k. We should be able to cope...
2085 public void Disconnect (bool reuseSocket)
2087 if (disposed && closed) {
2088 throw new ObjectDisposedException (GetType ().ToString ());
2093 Disconnect_internal (socket, reuseSocket, out error);
2097 /* ERROR_NOT_SUPPORTED */
2098 throw new PlatformNotSupportedException ();
2100 throw new SocketException (error);
2107 /* Do managed housekeeping here... */
2111 [MonoTODO ("Not implemented")]
2112 public SocketInformation DuplicateAndClose (int targetProcessId)
2114 /* Need to serialize this socket into a
2115 * SocketInformation struct, but must study
2116 * the MS implementation harder to figure out
2117 * behaviour as documentation is lacking
2119 throw new NotImplementedException ();
2123 public Socket EndAccept(IAsyncResult result) {
2127 return(EndAccept (out buffer, out bytes, result));
2131 public Socket EndAccept (out byte[] buffer,
2132 IAsyncResult asyncResult)
2136 return(EndAccept (out buffer, out bytes, asyncResult));
2145 Socket EndAccept (out byte[] buffer, out int bytesTransferred,
2146 IAsyncResult asyncResult)
2148 if (disposed && closed) {
2149 throw new ObjectDisposedException (GetType ().ToString ());
2152 if (asyncResult == null) {
2153 throw new ArgumentNullException ("asyncResult");
2156 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2158 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2161 if (!asyncResult.IsCompleted) {
2162 asyncResult.AsyncWaitHandle.WaitOne ();
2165 req.CheckIfThrowDelayedException ();
2167 buffer = req.Buffer;
2168 bytesTransferred = req.Total;
2173 public void EndConnect(IAsyncResult result) {
2174 if (disposed && closed)
2175 throw new ObjectDisposedException (GetType ().ToString ());
2178 throw new ArgumentNullException ("result");
2180 SocketAsyncResult req = result as SocketAsyncResult;
2182 throw new ArgumentException ("Invalid IAsyncResult", "result");
2184 if (!result.IsCompleted)
2185 result.AsyncWaitHandle.WaitOne();
2187 req.CheckIfThrowDelayedException();
2191 public void EndDisconnect (IAsyncResult asyncResult)
2193 if (disposed && closed) {
2194 throw new ObjectDisposedException (GetType ().ToString ());
2196 if (asyncResult == null) {
2197 throw new ArgumentNullException ("asyncResult");
2200 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2202 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2205 if (!asyncResult.IsCompleted) {
2206 asyncResult.AsyncWaitHandle.WaitOne ();
2209 req.CheckIfThrowDelayedException ();
2213 public int EndReceive(IAsyncResult result)
2217 return(EndReceive (result, out error));
2225 int EndReceive (IAsyncResult asyncResult,
2226 out SocketError errorCode)
2228 if (disposed && closed) {
2229 throw new ObjectDisposedException (GetType ().ToString ());
2231 if (asyncResult == null) {
2232 throw new ArgumentNullException ("asyncResult");
2235 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2237 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
2240 if (!asyncResult.IsCompleted) {
2241 asyncResult.AsyncWaitHandle.WaitOne ();
2244 errorCode = req.ErrorCode;
2245 req.CheckIfThrowDelayedException ();
2250 public int EndReceiveFrom(IAsyncResult result,
2251 ref EndPoint end_point) {
2252 if (disposed && closed)
2253 throw new ObjectDisposedException (GetType ().ToString ());
2256 throw new ArgumentNullException ("result");
2258 SocketAsyncResult req = result as SocketAsyncResult;
2260 throw new ArgumentException ("Invalid IAsyncResult", "result");
2262 if (!result.IsCompleted)
2263 result.AsyncWaitHandle.WaitOne();
2265 req.CheckIfThrowDelayedException();
2266 end_point = req.EndPoint;
2270 public int EndSend(IAsyncResult result)
2274 return(EndSend (result, out error));
2282 int EndSend (IAsyncResult asyncResult,
2283 out SocketError errorCode)
2285 if (disposed && closed) {
2286 throw new ObjectDisposedException (GetType ().ToString ());
2288 if (asyncResult == null) {
2289 throw new ArgumentNullException ("asyncResult");
2292 SocketAsyncResult req = asyncResult as SocketAsyncResult;
2294 throw new ArgumentException ("Invalid IAsyncResult", "result");
2297 if (!asyncResult.IsCompleted) {
2298 asyncResult.AsyncWaitHandle.WaitOne ();
2301 errorCode = req.ErrorCode;
2302 req.CheckIfThrowDelayedException ();
2307 public int EndSendTo(IAsyncResult result) {
2308 if (disposed && closed)
2309 throw new ObjectDisposedException (GetType ().ToString ());
2312 throw new ArgumentNullException ("result");
2314 SocketAsyncResult req = result as SocketAsyncResult;
2316 throw new ArgumentException ("Invalid IAsyncResult", "result");
2318 if (!result.IsCompleted)
2319 result.AsyncWaitHandle.WaitOne();
2321 req.CheckIfThrowDelayedException();
2325 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2326 private extern static void GetSocketOption_obj_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, out object obj_val, out int error);
2327 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2328 private extern static void GetSocketOption_arr_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val, out int error);
2330 public object GetSocketOption (SocketOptionLevel level, SocketOptionName name)
2332 if (disposed && closed)
2333 throw new ObjectDisposedException (GetType ().ToString ());
2338 GetSocketOption_obj_internal(socket, level, name,
2339 out obj_val, out error);
2342 throw new SocketException (error);
2345 if(name==SocketOptionName.Linger) {
2346 return((LingerOption)obj_val);
2347 } else if (name==SocketOptionName.AddMembership ||
2348 name==SocketOptionName.DropMembership) {
2349 return((MulticastOption)obj_val);
2350 } else if (obj_val is int) {
2351 return((int)obj_val);
2357 public void GetSocketOption (SocketOptionLevel level, SocketOptionName name, byte [] opt_value)
2359 if (disposed && closed)
2360 throw new ObjectDisposedException (GetType ().ToString ());
2364 GetSocketOption_arr_internal(socket, level, name,
2365 ref opt_value, out error);
2368 throw new SocketException (error);
2372 public byte [] GetSocketOption (SocketOptionLevel level, SocketOptionName name, int length)
2374 if (disposed && closed)
2375 throw new ObjectDisposedException (GetType ().ToString ());
2377 byte[] byte_val=new byte[length];
2380 GetSocketOption_arr_internal(socket, level, name,
2381 ref byte_val, out error);
2384 throw new SocketException (error);
2390 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
2391 // common options between UNIX and Winsock are FIONREAD,
2392 // FIONBIO and SIOCATMARK. Anything else will depend on the
2394 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2395 extern static int WSAIoctl (IntPtr sock, int ioctl_code,
2396 byte [] input, byte [] output,
2399 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
2402 throw new ObjectDisposedException (GetType ().ToString ());
2405 int result = WSAIoctl (socket, ioctl_code, in_value,
2406 out_value, out error);
2409 throw new SocketException (error);
2413 throw new InvalidOperationException ("Must use Blocking property instead.");
2420 public int IOControl (IOControlCode ioControlCode,
2421 byte[] optionInValue,
2422 byte[] optionOutValue)
2424 /* Probably just needs to mirror the int
2425 * overload, but more investigation needed.
2427 throw new NotImplementedException ();
2431 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2432 private extern static void Listen_internal(IntPtr sock,
2436 public void Listen (int backlog)
2438 if (disposed && closed)
2439 throw new ObjectDisposedException (GetType ().ToString ());
2442 /* TODO: check if this should be thrown in the
2446 throw new SocketException ((int)SocketError.InvalidArgument);
2452 Listen_internal(socket, backlog, out error);
2455 throw new SocketException (error);
2463 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2464 extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
2466 public bool Poll (int time_us, SelectMode mode)
2468 if (disposed && closed)
2469 throw new ObjectDisposedException (GetType ().ToString ());
2471 if (mode != SelectMode.SelectRead &&
2472 mode != SelectMode.SelectWrite &&
2473 mode != SelectMode.SelectError)
2474 throw new NotSupportedException ("'mode' parameter is not valid.");
2477 bool result = Poll_internal (socket, mode, time_us, out error);
2479 throw new SocketException (error);
2481 if (mode == SelectMode.SelectWrite &&
2483 connected == false) {
2484 /* Update the connected state; for
2485 * non-blocking Connect()s this is
2486 * when we can find out that the
2487 * connect succeeded.
2489 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
2497 /* This overload is needed as the async Connect method
2498 * also needs to check the socket error status, but
2499 * getsockopt(..., SO_ERROR) clears the error.
2501 private bool Poll (int time_us, SelectMode mode,
2502 out int socket_error)
2504 if (disposed && closed)
2505 throw new ObjectDisposedException (GetType ().ToString ());
2507 if (mode != SelectMode.SelectRead &&
2508 mode != SelectMode.SelectWrite &&
2509 mode != SelectMode.SelectError)
2510 throw new NotSupportedException ("'mode' parameter is not valid.");
2513 bool result = Poll_internal (socket, mode, time_us, out error);
2515 throw new SocketException (error);
2517 socket_error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
2519 if (mode == SelectMode.SelectWrite && result == true) {
2520 /* Update the connected state; for
2521 * non-blocking Connect()s this is
2522 * when we can find out that the
2523 * connect succeeded.
2525 if (socket_error == 0) {
2533 public int Receive (byte [] buf)
2535 if (disposed && closed)
2536 throw new ObjectDisposedException (GetType ().ToString ());
2539 throw new ArgumentNullException ("buf");
2543 int ret = Receive_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2545 if (error != SocketError.Success)
2546 throw new SocketException ((int) error);
2551 public int Receive (byte [] buf, SocketFlags flags)
2553 if (disposed && closed)
2554 throw new ObjectDisposedException (GetType ().ToString ());
2557 throw new ArgumentNullException ("buf");
2561 int ret = Receive_nochecks (buf, 0, buf.Length, flags, out error);
2563 if (error != SocketError.Success) {
2564 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2565 throw new SocketException ((int) error, "Operation timed out.");
2566 throw new SocketException ((int) error);
2572 public int Receive (byte [] buf, int size, SocketFlags flags)
2574 if (disposed && closed)
2575 throw new ObjectDisposedException (GetType ().ToString ());
2578 throw new ArgumentNullException ("buf");
2580 if (size < 0 || size > buf.Length)
2581 throw new ArgumentOutOfRangeException ("size");
2585 int ret = Receive_nochecks (buf, 0, size, flags, out error);
2587 if (error != SocketError.Success) {
2588 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2589 throw new SocketException ((int) error, "Operation timed out.");
2590 throw new SocketException ((int) error);
2596 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
2598 if (disposed && closed)
2599 throw new ObjectDisposedException (GetType ().ToString ());
2602 throw new ArgumentNullException ("buf");
2604 if (offset < 0 || offset > buf.Length)
2605 throw new ArgumentOutOfRangeException ("offset");
2607 if (size < 0 || offset + size > buf.Length)
2608 throw new ArgumentOutOfRangeException ("size");
2612 int ret = Receive_nochecks (buf, offset, size, flags, out error);
2614 if (error != SocketError.Success) {
2615 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2616 throw new SocketException ((int) error, "Operation timed out.");
2617 throw new SocketException ((int) error);
2624 public int Receive (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2626 if (disposed && closed)
2627 throw new ObjectDisposedException (GetType ().ToString ());
2630 throw new ArgumentNullException ("buf");
2632 if (offset < 0 || offset > buf.Length)
2633 throw new ArgumentOutOfRangeException ("offset");
2635 if (size < 0 || offset + size > buf.Length)
2636 throw new ArgumentOutOfRangeException ("size");
2638 return Receive_nochecks (buf, offset, size, flags, out error);
2642 public int Receive (IList<ArraySegment<byte>> buffers)
2644 /* For these generic IList overloads I need to
2645 * implement WSARecv in the runtime
2647 throw new NotImplementedException ();
2650 [CLSCompliant (false)]
2652 public int Receive (IList<ArraySegment<byte>> buffers,
2653 SocketFlags socketFlags)
2655 throw new NotImplementedException ();
2658 [CLSCompliant (false)]
2660 public int Receive (IList<ArraySegment<byte>> buffers,
2661 SocketFlags socketFlags,
2662 out SocketError errorCode)
2664 throw new NotImplementedException ();
2668 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2669 private extern static int Receive_internal(IntPtr sock,
2676 int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2679 int ret = Receive_internal (socket, buf, offset, size, flags, out nativeError);
2680 error = (SocketError) nativeError;
2681 if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
2689 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
2691 if (disposed && closed)
2692 throw new ObjectDisposedException (GetType ().ToString ());
2695 throw new ArgumentNullException ("buf");
2697 if (remote_end == null)
2698 throw new ArgumentNullException ("remote_end");
2700 return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
2703 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
2705 if (disposed && closed)
2706 throw new ObjectDisposedException (GetType ().ToString ());
2709 throw new ArgumentNullException ("buf");
2711 if (remote_end == null)
2712 throw new ArgumentNullException ("remote_end");
2715 return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
2718 public int ReceiveFrom (byte [] buf, int size, SocketFlags flags,
2719 ref EndPoint remote_end)
2721 if (disposed && closed)
2722 throw new ObjectDisposedException (GetType ().ToString ());
2725 throw new ArgumentNullException ("buf");
2727 if (remote_end == null)
2728 throw new ArgumentNullException ("remote_end");
2730 if (size < 0 || size > buf.Length)
2731 throw new ArgumentOutOfRangeException ("size");
2733 return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
2737 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2738 private extern static int RecvFrom_internal(IntPtr sock,
2743 ref SocketAddress sockaddr,
2746 public int ReceiveFrom (byte [] buf, int offset, int size, SocketFlags flags,
2747 ref EndPoint remote_end)
2749 if (disposed && closed)
2750 throw new ObjectDisposedException (GetType ().ToString ());
2753 throw new ArgumentNullException ("buf");
2755 if (remote_end == null)
2756 throw new ArgumentNullException ("remote_end");
2758 if (offset < 0 || offset > buf.Length)
2759 throw new ArgumentOutOfRangeException ("offset");
2761 if (size < 0 || offset + size > buf.Length)
2762 throw new ArgumentOutOfRangeException ("size");
2764 return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
2767 int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
2768 ref EndPoint remote_end)
2770 SocketAddress sockaddr = remote_end.Serialize();
2773 cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
2775 SocketError err = (SocketError) error;
2777 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2779 else if (err == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
2780 throw new SocketException (error, "Operation timed out.");
2782 throw new SocketException (error);
2791 // If sockaddr is null then we're a connection
2792 // oriented protocol and should ignore the
2793 // remote_end parameter (see MSDN
2794 // documentation for Socket.ReceiveFrom(...) )
2796 if ( sockaddr != null ) {
2797 // Stupidly, EndPoint.Create() is an
2799 remote_end = remote_end.Create (sockaddr);
2805 public int Send (byte [] buf)
2807 if (disposed && closed)
2808 throw new ObjectDisposedException (GetType ().ToString ());
2811 throw new ArgumentNullException ("buf");
2815 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
2817 if (error != SocketError.Success)
2818 throw new SocketException ((int) error);
2823 public int Send (byte [] buf, SocketFlags flags)
2825 if (disposed && closed)
2826 throw new ObjectDisposedException (GetType ().ToString ());
2829 throw new ArgumentNullException ("buf");
2833 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
2835 if (error != SocketError.Success)
2836 throw new SocketException ((int) error);
2841 public int Send (byte [] buf, int size, SocketFlags flags)
2843 if (disposed && closed)
2844 throw new ObjectDisposedException (GetType ().ToString ());
2847 throw new ArgumentNullException ("buf");
2849 if (size < 0 || size > buf.Length)
2850 throw new ArgumentOutOfRangeException ("size");
2854 int ret = Send_nochecks (buf, 0, size, flags, out error);
2856 if (error != SocketError.Success)
2857 throw new SocketException ((int) error);
2862 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
2864 if (disposed && closed)
2865 throw new ObjectDisposedException (GetType ().ToString ());
2868 throw new ArgumentNullException ("buffer");
2870 if (offset < 0 || offset > buf.Length)
2871 throw new ArgumentOutOfRangeException ("offset");
2873 if (size < 0 || offset + size > buf.Length)
2874 throw new ArgumentOutOfRangeException ("size");
2878 int ret = Send_nochecks (buf, offset, size, flags, out error);
2880 if (error != SocketError.Success)
2881 throw new SocketException ((int) error);
2887 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2889 if (disposed && closed)
2890 throw new ObjectDisposedException (GetType ().ToString ());
2893 throw new ArgumentNullException ("buffer");
2895 if (offset < 0 || offset > buf.Length)
2896 throw new ArgumentOutOfRangeException ("offset");
2898 if (size < 0 || offset + size > buf.Length)
2899 throw new ArgumentOutOfRangeException ("size");
2901 return Send_nochecks (buf, offset, size, flags, out error);
2905 public int Send (IList<ArraySegment<byte>> buffers)
2907 /* For these generic IList overloads I need to
2908 * implement WSASend in the runtime
2910 throw new NotImplementedException ();
2914 public int Send (IList<ArraySegment<byte>> buffers,
2915 SocketFlags socketFlags)
2917 throw new NotImplementedException ();
2920 [CLSCompliant (false)]
2922 public int Send (IList<ArraySegment<byte>> buffers,
2923 SocketFlags socketFlags,
2924 out SocketError errorCode)
2926 throw new NotImplementedException ();
2930 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2931 private extern static int Send_internal(IntPtr sock,
2932 byte[] buf, int offset,
2937 int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
2940 error = SocketError.Success;
2946 int ret = Send_internal (socket, buf, offset, size, flags, out nativeError);
2948 error = (SocketError)nativeError;
2950 if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
2958 public int SendTo (byte [] buffer, EndPoint remote_end)
2960 if (disposed && closed)
2961 throw new ObjectDisposedException (GetType ().ToString ());
2964 throw new ArgumentNullException ("buffer");
2966 if (remote_end == null)
2967 throw new ArgumentNullException ("remote_end");
2969 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2972 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2974 if (disposed && closed)
2975 throw new ObjectDisposedException (GetType ().ToString ());
2978 throw new ArgumentNullException ("buffer");
2980 if (remote_end == null)
2981 throw new ArgumentNullException ("remote_end");
2983 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2986 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2988 if (disposed && closed)
2989 throw new ObjectDisposedException (GetType ().ToString ());
2992 throw new ArgumentNullException ("buffer");
2994 if (remote_end == null)
2995 throw new ArgumentNullException ("remote_end");
2997 if (size < 0 || size > buffer.Length)
2998 throw new ArgumentOutOfRangeException ("size");
3000 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
3003 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3004 private extern static int SendTo_internal(IntPtr sock,
3012 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
3013 EndPoint remote_end)
3015 if (disposed && closed)
3016 throw new ObjectDisposedException (GetType ().ToString ());
3019 throw new ArgumentNullException ("buffer");
3021 if (remote_end == null)
3022 throw new ArgumentNullException("remote_end");
3024 if (offset < 0 || offset > buffer.Length)
3025 throw new ArgumentOutOfRangeException ("offset");
3027 if (size < 0 || offset + size > buffer.Length)
3028 throw new ArgumentOutOfRangeException ("size");
3030 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
3033 int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
3034 EndPoint remote_end)
3036 SocketAddress sockaddr = remote_end.Serialize ();
3040 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
3042 SocketError err = (SocketError) error;
3044 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
3047 throw new SocketException (error);
3059 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3060 private extern static void SetSocketOption_internal (IntPtr socket, SocketOptionLevel level,
3061 SocketOptionName name, object obj_val,
3062 byte [] byte_val, int int_val,
3065 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
3067 if (disposed && closed)
3068 throw new ObjectDisposedException (GetType ().ToString ());
3072 SetSocketOption_internal(socket, level, name, null,
3073 opt_value, 0, out error);
3076 throw new SocketException (error);
3080 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
3082 if (disposed && closed)
3083 throw new ObjectDisposedException (GetType ().ToString ());
3087 SetSocketOption_internal(socket, level, name, null,
3088 null, opt_value, out error);
3091 throw new SocketException (error);
3095 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
3098 if (disposed && closed)
3099 throw new ObjectDisposedException (GetType ().ToString ());
3101 if(opt_value==null) {
3102 throw new ArgumentNullException("opt_value");
3106 /* From MS documentation on SetSocketOption: "For an
3107 * option with a Boolean data type, specify a nonzero
3108 * value to enable the option, and a zero value to
3109 * disable the option."
3110 * Booleans are only handled in 2.0
3113 if (opt_value is System.Boolean) {
3115 bool bool_val = (bool) opt_value;
3116 int int_val = (bool_val) ? 1 : 0;
3118 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
3120 throw new ArgumentException ("Use an integer 1 (true) or 0 (false) instead of a boolean.", "opt_value");
3123 SetSocketOption_internal (socket, level, name, opt_value, null, 0, out error);
3127 throw new SocketException (error);
3131 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue)
3133 if (disposed && closed)
3134 throw new ObjectDisposedException (GetType ().ToString ());
3137 int int_val = (optionValue) ? 1 : 0;
3138 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
3140 throw new SocketException (error);
3143 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3144 private extern static void Shutdown_internal(IntPtr socket, SocketShutdown how, out int error);
3146 public void Shutdown (SocketShutdown how)
3148 if (disposed && closed)
3149 throw new ObjectDisposedException (GetType ().ToString ());
3153 Shutdown_internal(socket, how, out error);
3156 throw new SocketException (error);
3160 public override int GetHashCode ()
3162 return (int) socket;
3165 protected virtual void Dispose (bool explicitDisposing)
3172 if ((int) socket != -1) {
3176 socket = (IntPtr) (-1);
3177 Close_internal (x, out error);
3178 if (blocking_thread != null) {
3179 blocking_thread.Abort ();
3180 blocking_thread = null;
3184 throw new SocketException (error);
3188 void IDisposable.Dispose ()
3191 GC.SuppressFinalize (this);