Fix bug #311: On LinkedList.Clear, detach each node instead of dropping them en masse.
[mono.git] / mcs / class / System / System.Net.Sockets / Socket.jvm.cs
1 // System.Net.Sockets.Socket.cs
2 //
3 // Authors:
4 //    Phillip Pearson (pp@myelin.co.nz)
5 //    Dick Porter <dick@ximian.com>
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
9 //    http://www.myelin.co.nz
10 // (c) 2004 Novell, Inc. (http://www.novell.com)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.Net.Configuration;
37 using System.Runtime.InteropServices;
38 using System.Threading;
39
40 namespace System.Net.Sockets 
41 {
42         public class Socket : IDisposable 
43         {
44                 enum SocketOperation 
45                 {
46                         Accept,
47                         Connect,
48                         Receive,
49                         ReceiveFrom,
50                         Send,
51                         SendTo
52                 }
53
54                 [StructLayout (LayoutKind.Sequential)]
55                 private sealed class SocketAsyncResult: IAsyncResult 
56                 {
57                         /* Same structure in the runtime */
58                         public Socket Sock;
59 #if !TARGET_JVM
60                         public IntPtr handle;
61 #else
62                         public GHSocket handle;
63 #endif
64                         object state;
65                         AsyncCallback callback;
66                         WaitHandle waithandle;
67
68                         Exception delayedException;
69
70                         public EndPoint EndPoint;       // Connect,ReceiveFrom,SendTo
71                         public byte [] Buffer;          // Receive,ReceiveFrom,Send,SendTo
72                         public int Offset;              // Receive,ReceiveFrom,Send,SendTo
73                         public int Size;                // Receive,ReceiveFrom,Send,SendTo
74                         public SocketFlags SockFlags;   // Receive,ReceiveFrom,Send,SendTo
75
76                         // Return values
77                         Socket acc_socket;
78                         int total;
79
80                         bool completed_sync;
81                         bool completed;
82                         public bool blocking;
83                         internal int error;
84                         SocketOperation operation;
85                         public object ares;
86
87                         public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
88                         {
89                                 this.Sock = sock;
90                                 this.blocking = sock.blocking;
91                                 this.handle = sock.socket;
92                                 this.state = state;
93                                 this.callback = callback;
94                                 this.operation = operation;
95                                 SockFlags = SocketFlags.None;
96                         }
97
98                         public void CheckIfThrowDelayedException ()
99                         {
100                                 if (delayedException != null)
101                                         throw delayedException;
102
103                                 if (error != 0)
104                                         throw new SocketException (error);
105                         }
106
107                         void CompleteAllOnDispose (Queue queue)
108                         {
109                                 object [] pending = queue.ToArray ();
110                                 queue.Clear ();
111
112                                 WaitCallback cb;
113                                 for (int i = 0; i < pending.Length; i++) 
114                                 {
115                                         SocketAsyncResult ares = (SocketAsyncResult) pending [i];
116                                         cb = new WaitCallback (ares.CompleteDisposed);
117                                         ThreadPool.QueueUserWorkItem (cb, null);
118                                 }
119                         }
120
121                         void CompleteDisposed (object unused)
122                         {
123                                 Complete ();
124                         }
125
126                         public void Complete ()
127                         {
128                                 if (operation != SocketOperation.Receive && Sock.disposed)
129                                         delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
130
131                                 IsCompleted = true;
132
133                                 Queue queue = null;
134                                 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) 
135                                 {
136                                         queue = Sock.readQ;
137                                 } 
138                                 else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) 
139                                 {
140                                         queue = Sock.writeQ;
141                                 }
142
143                                 if (queue != null) 
144                                 {
145                                         SocketAsyncCall sac = null;
146                                         SocketAsyncResult req = null;
147                                         lock (queue) 
148                                         {
149                                                 queue.Dequeue (); // remove ourselves
150                                                 if (queue.Count > 0) 
151                                                 {
152                                                         req = (SocketAsyncResult) queue.Peek ();
153                                                         if (!Sock.disposed) 
154                                                         {
155                                                                 Worker worker = new Worker (req);
156                                                                 sac = GetDelegate (worker, req.operation);
157                                                         } 
158                                                         else 
159                                                         {
160                                                                 CompleteAllOnDispose (queue);
161                                                         }
162                                                 }
163                                         }
164
165                                         if (sac != null)
166                                                 sac.BeginInvoke (null, req);
167                                 }
168
169                                 if (callback != null)
170                                         callback (this);
171                         }
172
173                         SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
174                         {
175                                 switch (op) 
176                                 {
177                                         case SocketOperation.Receive:
178                                                 return new SocketAsyncCall (worker.Receive);
179                                         case SocketOperation.ReceiveFrom:
180                                                 return new SocketAsyncCall (worker.ReceiveFrom);
181                                         case SocketOperation.Send:
182                                                 return new SocketAsyncCall (worker.Send);
183                                         case SocketOperation.SendTo:
184                                                 return new SocketAsyncCall (worker.SendTo);
185                                         default:
186                                                 return null; // never happens
187                                 }
188                         }
189
190                         public void Complete (bool synch)
191                         {
192                                 completed_sync = synch;
193                                 Complete ();
194                         }
195
196                         public void Complete (int total)
197                         {
198                                 this.total = total;
199                                 Complete ();
200                         }
201                         
202                         public void Complete (Exception e, bool synch)
203                         {
204                                 completed_sync = synch;
205                                 delayedException = e;
206                                 Complete ();
207                         }
208
209                         public void Complete (Exception e)
210                         {
211                                 delayedException = e;
212                                 Complete ();
213                         }
214
215                         public void Complete (Socket s)
216                         {
217                                 acc_socket = s;
218                                 Complete ();
219                         }
220
221                         public object AsyncState 
222                         {
223                                 get 
224                                 {
225                                         return state;
226                                 }
227                         }
228
229                         public WaitHandle AsyncWaitHandle 
230                         {
231                                 get 
232                                 {
233                                         lock (this) 
234                                         {
235                                                 if (waithandle == null)
236                                                         waithandle = new ManualResetEvent (completed);
237                                         }
238
239                                         return waithandle;
240                                 }
241                                 set 
242                                 {
243                                         waithandle=value;
244                                 }
245                         }
246
247                         public bool CompletedSynchronously 
248                         {
249                                 get 
250                                 {
251                                         return(completed_sync);
252                                 }
253                         }
254
255                         public bool IsCompleted 
256                         {
257                                 get 
258                                 {
259                                         return(completed);
260                                 }
261                                 set 
262                                 {
263                                         completed=value;
264                                         lock (this) 
265                                         {
266                                                 if (waithandle != null && value) 
267                                                 {
268                                                         ((ManualResetEvent) waithandle).Set ();
269                                                 }
270                                         }
271                                 }
272                         }
273                         
274                         public Socket Socket 
275                         {
276                                 get 
277                                 {
278                                         return acc_socket;
279                                 }
280                         }
281
282                         public int Total 
283                         {
284                                 get 
285                                 {
286                                         return total;
287                                 }
288                                 set 
289                                 { 
290                                         total = value; 
291                                 }
292                         }
293                 }
294
295                 private sealed class Worker 
296                 {
297                         SocketAsyncResult result;
298
299                         public Worker (SocketAsyncResult ares)
300                         {
301                                 this.result = ares;
302                         }
303                         
304                         public void Accept ()
305                         {
306                                 Socket acc_socket = null;
307                                 try 
308                                 {
309                                         acc_socket = result.Sock.Accept ();
310                                 } 
311                                 catch (Exception e) 
312                                 {
313                                         result.Complete (e);
314                                         return;
315                                 }
316
317                                 result.Complete (acc_socket);
318                         }
319
320                         public void Connect ()
321                         {
322                                 try 
323                                 {
324                                         result.Sock.Connect (result.EndPoint);
325                                         result.Sock.connected = true;
326                                 } 
327                                 catch (Exception e) 
328                                 {
329                                         result.Complete (e);
330                                         return;
331                                 }
332
333                                 result.Complete ();
334                         }
335
336 #if !TARGET_JVM
337                         public void Receive ()
338                         {
339                                 // Actual recv() done in the runtime
340                                 result.Complete ();
341                         }
342 #else
343                         public void Receive ()
344                         {
345                                 int total = 0;
346                                 try 
347                                 {
348                                         total = result.Sock.Receive_nochecks (result.Buffer,
349                                                 result.Offset,
350                                                 result.Size,
351                                                 result.SockFlags);
352                                 } 
353                                 catch (Exception e) 
354                                 {
355                                         result.Complete (e);
356                                         return;
357                                 }
358
359                                 result.Complete (total);
360                         }
361 #endif
362
363                         public void ReceiveFrom ()
364                         {
365                                 int total = 0;
366                                 try 
367                                 {
368                                         total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
369                                                 result.Offset,
370                                                 result.Size,
371                                                 result.SockFlags,
372                                                 ref result.EndPoint);
373                                 } 
374                                 catch (Exception e) 
375                                 {
376                                         result.Complete (e);
377                                         return;
378                                 }
379
380                                 result.Complete (total);
381                         }
382
383                         int send_so_far;
384
385                         void UpdateSendValues (int last_sent)
386                         {
387                                 if (result.error == 0) 
388                                 {
389                                         send_so_far += last_sent;
390                                         result.Offset += last_sent;
391                                         result.Size -= last_sent;
392                                 }
393                         }
394
395 #if !TARGET_JVM
396                         public void Send ()
397                         {
398                                 // Actual send() done in the runtime
399                                 if (result.error == 0) 
400                                 {
401                                         UpdateSendValues (result.Total);
402                                         if (result.Sock.disposed) 
403                                         {
404                                                 result.Complete ();
405                                                 return;
406                                         }
407
408                                         if (result.Size > 0) 
409                                         {
410                                                 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
411                                                 sac.BeginInvoke (null, result);
412                                                 return; // Have to finish writing everything. See bug #74475.
413                                         }
414                                         result.Total = send_so_far;
415                                 }
416                                 result.Complete ();
417                         }
418 #else
419                         public void Send ()
420                         {
421                                 int total = 0;
422                                 try 
423                                 {
424                                         total = result.Sock.Send_nochecks (result.Buffer,
425                                                 result.Offset,
426                                                 result.Size,
427                                                 result.SockFlags);
428
429                                         UpdateSendValues (total);
430                                         if (result.Size > 0) 
431                                         {
432                                                 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
433                                                 sac.BeginInvoke (null, result);
434                                                 return; // Have to finish writing everything. See bug #74475.
435                                         }
436                                         result.Total = send_so_far;
437                                 } 
438                                 catch (Exception e) 
439                                 {
440                                         result.Complete (e);
441                                         return;
442                                 }
443
444                                 result.Complete ();
445                         }
446 #endif
447
448                         public void SendTo ()
449                         {
450                                 int total = 0;
451                                 try 
452                                 {
453                                         total = result.Sock.SendTo_nochecks (result.Buffer,
454                                                 result.Offset,
455                                                 result.Size,
456                                                 result.SockFlags,
457                                                 result.EndPoint);
458
459                                         UpdateSendValues (total);
460                                         if (result.Size > 0) 
461                                         {
462                                                 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
463                                                 sac.BeginInvoke (null, result);
464                                                 return; // Have to finish writing everything. See bug #74475.
465                                         }
466                                         result.Total = send_so_far;
467                                 } 
468                                 catch (Exception e) 
469                                 {
470                                         result.Complete (e);
471                                         return;
472                                 }
473
474                                 result.Complete ();
475                         }
476                 }
477
478                         
479                 /* the field "socket" is looked up by name by the runtime */
480 #if !TARGET_JVM
481                 private IntPtr socket;
482 #else
483                 private GHSocket socket;
484 #endif
485                 private AddressFamily address_family;
486                 private SocketType socket_type;
487                 private ProtocolType protocol_type;
488                 internal bool blocking=true;
489                 private Queue readQ = new Queue (2);
490                 private Queue writeQ = new Queue (2);
491                 
492
493                 delegate void SocketAsyncCall ();
494                 /*
495                  *      These two fields are looked up by name by the runtime, don't change
496                  *  their name without also updating the runtime code.
497                  */
498                 private static int ipv4Supported = -1, ipv6Supported = -1;
499
500                 /* When true, the socket was connected at the time of
501                  * the last IO operation
502                  */
503                 private bool connected=false;
504                 /* true if we called Close_internal */
505                 private bool closed;
506                 internal bool disposed;
507
508                 /* Used in LocalEndPoint and RemoteEndPoint if the
509                  * Mono.Posix assembly is available
510                  */
511                 private static object unixendpoint=null;
512                 private static Type unixendpointtype=null;
513                 
514                 static void AddSockets (ArrayList sockets, IList list, string name)
515                 {
516                         if (list != null) 
517                         {
518                                 foreach (Socket sock in list) 
519                                 {
520                                         if (sock == null) // MS throws a NullRef
521                                                 throw new ArgumentNullException (name, "Contains a null element");
522                                         sockets.Add (sock);
523                                 }
524                         }
525
526                         sockets.Add (null);
527                 }
528
529 #if !TARGET_JVM
530                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
531                 private extern static void Select_internal (ref Socket [] sockets,
532                                                         int microSeconds,
533                                                         out int error);
534 #else
535                 private static void Select_internal (ref Socket [] sockets, int microSeconds, out int error)
536                 {
537                         GHSocketFactory.Select_internal(ref sockets, microSeconds, out error);
538                 }
539 #endif
540
541                 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
542                 {
543                         ArrayList list = new ArrayList ();
544                         AddSockets (list, checkRead, "checkRead");
545                         AddSockets (list, checkWrite, "checkWrite");
546                         AddSockets (list, checkError, "checkError");
547
548                         if (list.Count == 3) 
549                         {
550                                 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
551                                         "All the lists are null or empty.");
552                         }
553
554                         int error;
555                         /*
556                          * The 'sockets' array contains: READ socket 0-n, null,
557                          *                               WRITE socket 0-n, null,
558                          *                               ERROR socket 0-n, null
559                          */
560                         Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
561                         Select_internal (ref sockets, microSeconds, out error);
562
563                         if (error != 0)
564                                 throw new SocketException (error);
565
566                         if (checkRead != null)
567                                 checkRead.Clear ();
568
569                         if (checkWrite != null)
570                                 checkWrite.Clear ();
571
572                         if (checkError != null)
573                                 checkError.Clear ();
574
575                         if (sockets == null)
576                                 return;
577
578                         int mode = 0;
579                         int count = sockets.Length;
580                         IList currentList = checkRead;
581                         for (int i = 0; i < count; i++) 
582                         {
583                                 Socket sock = sockets [i];
584                                 if (sock == null) 
585                                 { // separator
586                                         currentList = (mode == 0) ? checkWrite : checkError;
587                                         mode++;
588                                         continue;
589                                 }
590
591                                 if (currentList != null) 
592                                 {
593                                         sock.connected = true;
594                                         currentList.Add (sock);
595                                 }
596                         }
597                 }
598
599 #if !TARGET_JVM
600                 static Socket() 
601                 {
602                         Assembly ass;
603                         
604                         try {
605                                 ass = Assembly.Load (Consts.AssemblyMono_Posix);
606                         } catch (FileNotFoundException) {
607                                 return;
608                         }
609                                 
610                         unixendpointtype=ass.GetType("Mono.Posix.UnixEndPoint");
611
612                         /* The endpoint Create() method is an instance
613                          * method :-(
614                          */
615                         Type[] arg_types=new Type[1];
616                         arg_types[0]=typeof(string);
617                         ConstructorInfo cons=unixendpointtype.GetConstructor(arg_types);
618
619                         object[] args=new object[1];
620                         args[0]="";
621
622                         unixendpoint=cons.Invoke(args);
623                 }
624 #endif
625
626 #if !TARGET_JVM
627                 // private constructor used by Accept, which already
628                 // has a socket handle to use
629                 private Socket(AddressFamily family, SocketType type,
630                         ProtocolType proto, IntPtr sock) 
631 #else
632                 // private constructor used by Accept, which already
633                 // has a socket handle to use
634                 private Socket(AddressFamily family, SocketType type,
635                         ProtocolType proto, GHSocket sock) 
636                 {
637 #endif
638                         address_family=family;
639                         socket_type=type;
640                         protocol_type=proto;
641                         
642                         socket=sock;
643                         connected=true;
644                 }
645
646
647 #if !TARGET_JVM
648                 // Creates a new system socket, returning the handle
649                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
650                 private extern IntPtr Socket_internal(AddressFamily family,
651                         SocketType type,
652                         ProtocolType proto,
653                         out int error);
654 #else
655                 private GHSocket Socket_internal(AddressFamily family,
656                         SocketType type,
657                         ProtocolType proto,
658                         out int error)
659                 {
660                         return GHSocketFactory.Socket_internal(family, type, proto, out error);
661                 }
662 #endif  
663
664                 public Socket(AddressFamily family, SocketType type,
665                         ProtocolType proto) 
666                 {
667                         address_family=family;
668                         socket_type=type;
669                         protocol_type=proto;
670                         int error;
671                         
672                         socket=Socket_internal(family, type, proto, out error);
673                         if (error != 0) {
674                                 throw new SocketException (error);
675                         }
676                 }
677
678                 public AddressFamily AddressFamily 
679                 {
680                         get 
681                         {
682                                 return(address_family);
683                         }
684                 }
685
686 #if !TARGET_JVM
687                 // Returns the amount of data waiting to be read on socket
688                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
689                 private extern static int Available_internal(IntPtr socket,
690                         out int error);
691 #else
692                 private int Available_internal(GHSocket socket, out int error)
693                 {
694                         return socket.Available_internal(out error);
695                 }
696 #endif
697
698                 public int Available 
699                 {
700                         get 
701                         {
702                                 EnsureStillUsable();
703
704                                 int ret, error;
705                                 
706                                 ret = Available_internal(socket, out error);
707
708                                 if (error != 0) 
709                                 {
710                                         throw new SocketException (error);
711                                 }
712
713                                 return(ret);
714                         }
715                 }
716
717 #if !TARGET_JVM
718                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
719                 private extern static void Blocking_internal(IntPtr socket,
720                         bool block,
721                         out int error);
722 #else
723                 private void Blocking_internal(GHSocket socket, bool block,     out int error)
724                 {
725                         socket.Blocking_internal(block, out error);
726                 }
727 #endif
728
729                 public bool Blocking 
730                 {
731                         get 
732                         {
733                                 return(blocking);
734                         }
735                         set 
736                         {
737                                 EnsureStillUsable();
738
739                                 int error;
740                                 
741                                 Blocking_internal(socket, value, out error);
742
743                                 if (error != 0) {
744                                         throw new SocketException (error);
745                                 }
746                                 
747                                 blocking=value;
748                         }
749                 }
750
751                 public bool Connected 
752                 {
753                         get 
754                         {
755                                 return(connected);
756                         }
757                 }
758
759 #if !TARGET_JVM
760                 public IntPtr Handle 
761                 {
762                         get 
763                         {
764                                 return(socket);
765                         }
766                 }
767 #else
768                 public IntPtr Handle 
769                 {
770                         get 
771                         {
772                                 throw new NotImplementedException ();
773                         }
774                 }
775
776                 internal GHSocket GHHandle 
777                 {
778                         get 
779                         {
780                                 return socket;
781                         }
782                 }
783 #endif
784
785 #if !TARGET_JVM
786                 // Returns the local endpoint details in addr and port
787                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
788                 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
789
790                 [MonoTODO("Support non-IP endpoints")]
791                 public EndPoint LocalEndPoint 
792                 {
793                         get 
794                         {
795                                 if (disposed && closed)
796                                         throw new ObjectDisposedException (GetType ().ToString ());
797
798                                 SocketAddress sa;
799                                 int error;
800                                 
801                                 sa=LocalEndPoint_internal(socket, out error);
802
803                                 if (error != 0) {
804                                         throw new SocketException (error);
805                                 }
806
807                                 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6) {
808                                         // Stupidly, EndPoint.Create() is an
809                                         // instance method
810                                         return new IPEndPoint(0, 0).Create(sa);
811                                 } else if (sa.Family==AddressFamily.Unix &&
812                                            unixendpoint!=null) {
813                                         return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
814                                 } else {
815                                         throw new NotImplementedException();
816                                 }
817                         }
818                 }
819 #else
820                 private EndPoint LocalEndPoint_internal(GHSocket socket, out int error)
821                 {
822                         return socket.LocalEndPoint_internal(out error);
823                 }
824
825                 public EndPoint LocalEndPoint 
826                 {
827                         get 
828                         {
829                                 EnsureStillUsable();
830
831                                 int error;
832
833                                 EndPoint ret = LocalEndPoint_internal(socket, out error);
834
835                                 if (error != 0) 
836                                 {
837                                         throw new SocketException (error);
838                                 }
839
840                                 return ret;
841                         }
842                 }
843 #endif
844
845                         public ProtocolType ProtocolType 
846                 {
847                         get 
848                         {
849                                 return(protocol_type);
850                         }
851                 }
852
853 #if !TARGET_JVM
854                 // Returns the remote endpoint details in addr and port
855                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
856                 private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
857
858                 [MonoTODO("Support non-IP endpoints")]
859                 public EndPoint RemoteEndPoint 
860                 {
861                         get 
862                         {
863                                 if (disposed && closed)
864                                         throw new ObjectDisposedException (GetType ().ToString ());
865
866                                 SocketAddress sa;
867                                 int error;
868                                 
869                                 sa=RemoteEndPoint_internal(socket, out error);
870
871                                 if (error != 0) {
872                                         throw new SocketException (error);
873                                 }
874
875                                 if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6 ) {
876                                         // Stupidly, EndPoint.Create() is an
877                                         // instance method
878                                         return new IPEndPoint(0, 0).Create(sa);
879                                 } else if (sa.Family==AddressFamily.Unix &&
880                                            unixendpoint!=null) {
881                                         return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
882                                 } else {
883                                         throw new NotImplementedException();
884                                 }
885                         }
886                 }
887 #else
888                 private EndPoint RemoteEndPoint_internal(GHSocket socket, out int error)
889                 {
890                         return socket.RemoteEndPoint_internal(out error);
891                 }
892
893                 public EndPoint RemoteEndPoint 
894                 {
895                         get 
896                         {
897                                 EnsureStillUsable();
898
899                                 int error;
900
901                                 EndPoint ret = RemoteEndPoint_internal(socket, out error);
902
903                                 if (error != 0) 
904                                 {
905                                         throw new SocketException (error);
906                                 }
907
908                                 return ret;
909                         }
910                 }
911 #endif
912
913                 public SocketType SocketType 
914                 {
915                         get 
916                         {
917                                 return(socket_type);
918                         }
919                 }
920
921 #if NET_1_1
922                 public static bool SupportsIPv4 
923                 {
924                         get 
925                         {
926                                 CheckProtocolSupport();
927                                 return ipv4Supported == 1;
928                         }
929                 }
930
931                 public static bool SupportsIPv6 
932                 {
933                         get 
934                         {
935                                 CheckProtocolSupport();
936                                 return ipv6Supported == 1;
937                         }
938                 }
939 #else
940                 internal static bool SupportsIPv4 
941                 {
942                         get 
943                         {
944                                 return true;
945                         }
946                 }
947
948                 internal static bool SupportsIPv6 
949                 {
950                         get 
951                         {
952                                 return false;
953                         }
954                 }
955 #endif
956
957                 internal static void CheckProtocolSupport()
958                 {
959                         if(ipv4Supported == -1) 
960                         {
961                                 try  
962                                 {
963                                         Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
964                                         tmp.Close();
965
966                                         ipv4Supported = 1;
967                                 }
968                                 catch 
969                                 {
970                                         ipv4Supported = 0;
971                                 }
972                         }
973
974                         if(ipv6Supported == -1) 
975                         {
976 #if NET_2_0 && CONFIGURATION_DEP
977                                 SettingsSection config;
978                                 config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
979                                 if (config != null)
980                                         ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
981 #else
982                                 NetConfig config = (NetConfig)System.Configuration.ConfigurationSettings.GetConfig("system.net/settings");
983
984                                 if(config != null)
985                                         ipv6Supported = config.ipv6Enabled?-1:0;
986 #endif
987                                 if(ipv6Supported != 0) 
988                                 {
989                                         try 
990                                         {
991                                                 Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
992                                                 tmp.Close();
993
994                                                 ipv6Supported = 1;
995                                         }
996                                         catch { }
997                                 }
998                         }
999                 }
1000
1001 #if !TARGET_JVM
1002                 // Creates a new system socket, returning the handle
1003                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1004                 private extern static IntPtr Accept_internal(IntPtr sock,
1005                         out int error);
1006 #else
1007                 private GHSocket Accept_internal(GHSocket sock, out int error)
1008                 {
1009                         return sock.Accept_internal(out error);
1010                 }
1011 #endif
1012
1013                 public Socket Accept() 
1014                 {
1015                         EnsureStillUsable();
1016
1017                         int error = 0;
1018 #if !TARGET_JVM
1019                         IntPtr sock = (IntPtr) (-1);
1020 #else
1021                         GHSocket sock = null;
1022 #endif
1023                         sock = Accept_internal(socket, out error);
1024                         if (error != 0) {
1025                                 throw new SocketException (error);
1026                         }
1027                         
1028                         Socket accepted = new Socket(this.AddressFamily,
1029                                                      this.SocketType,
1030                                                      this.ProtocolType, sock);
1031
1032                         accepted.Blocking = this.Blocking;
1033                         return(accepted);
1034                 }
1035
1036                 public IAsyncResult BeginAccept(AsyncCallback callback,
1037                         object state) 
1038                 {
1039
1040                         EnsureStillUsable();
1041
1042                         SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
1043                         Worker worker = new Worker (req);
1044                         SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
1045                         sac.BeginInvoke (null, req);
1046                         return(req);
1047                 }
1048
1049                 public IAsyncResult BeginConnect(EndPoint end_point,
1050                         AsyncCallback callback,
1051                         object state) 
1052                 {
1053
1054                         EnsureStillUsable();
1055
1056                         if (end_point == null)
1057                                 throw new ArgumentNullException ("end_point");
1058
1059                         SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1060                         req.EndPoint = end_point;
1061
1062                         // Bug #75154: Connect() should not succeed for .Any addresses.
1063                         if (end_point is IPEndPoint) 
1064                         {
1065                                 IPEndPoint ep = (IPEndPoint) end_point;
1066                                 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) 
1067                                 {
1068                                         req.Complete (new SocketException (10049), true);
1069                                         return req;
1070                                 }
1071                         }
1072
1073                         int error = 0;
1074                         if (!blocking) 
1075                         {
1076 #if !TARGET_JVM
1077                                 SocketAddress serial = end_point.Serialize ();
1078                                 Connect_internal (socket, serial, out error);
1079 #else
1080                                 Connect_internal (socket, end_point, out error);
1081 #endif
1082                                 if (error == 0) 
1083                                 {
1084                                         // succeeded synch
1085                                         connected = true;
1086                                         req.Complete (true);
1087                                 } 
1088                                 else if (error != 10036 && error != 10035) 
1089                                 {
1090                                         // error synch
1091                                         connected = false;
1092                                         req.Complete (new SocketException (error), true);
1093                                 }
1094                         }
1095
1096                         if (blocking || error == 10036 || error == 10035) 
1097                         {
1098                                 // continue asynch
1099                                 connected = false;
1100                                 Worker worker = new Worker (req);
1101                                 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1102                                 sac.BeginInvoke (null, req);
1103                         }
1104
1105                         return(req);
1106                 }
1107
1108                 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1109                         int size,
1110                         SocketFlags socket_flags,
1111                         AsyncCallback callback,
1112                         object state) 
1113                 {
1114
1115                         EnsureStillUsable();
1116
1117                         if (buffer == null)
1118                                 throw new ArgumentNullException ("buffer");
1119
1120                         if (offset < 0 || offset > buffer.Length)
1121                                 throw new ArgumentOutOfRangeException ("offset");
1122
1123                         if (size < 0 || offset + size > buffer.Length)
1124                                 throw new ArgumentOutOfRangeException ("size");
1125
1126                         SocketAsyncResult req;
1127                         lock (readQ) 
1128                         {
1129                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
1130                                 req.Buffer = buffer;
1131                                 req.Offset = offset;
1132                                 req.Size = size;
1133                                 req.SockFlags = socket_flags;
1134                                 readQ.Enqueue (req);
1135                                 if (readQ.Count == 1) 
1136                                 {
1137                                         Worker worker = new Worker (req);
1138                                         SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1139                                         sac.BeginInvoke (null, req);
1140                                 }
1141                         }
1142
1143                         return req;
1144                 }
1145
1146                 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
1147                         int size,
1148                         SocketFlags socket_flags,
1149                         ref EndPoint remote_end,
1150                         AsyncCallback callback,
1151                         object state) 
1152                 {
1153                         EnsureStillUsable();
1154
1155                         if (buffer == null)
1156                                 throw new ArgumentNullException ("buffer");
1157
1158                         if (offset < 0)
1159                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1160
1161                         if (size < 0)
1162                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1163
1164                         if (offset + size > buffer.Length)
1165                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1166
1167                         SocketAsyncResult req;
1168                         lock (readQ) 
1169                         {
1170                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
1171                                 req.Buffer = buffer;
1172                                 req.Offset = offset;
1173                                 req.Size = size;
1174                                 req.SockFlags = socket_flags;
1175                                 req.EndPoint = remote_end;
1176                                 readQ.Enqueue (req);
1177                                 if (readQ.Count == 1) 
1178                                 {
1179                                         Worker worker = new Worker (req);
1180                                         SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1181                                         sac.BeginInvoke (null, req);
1182                                 }
1183                         }
1184                         return req;
1185                 }
1186
1187                 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1188                         AsyncCallback callback, object state)
1189                 {
1190                         EnsureStillUsable();
1191
1192                         if (buffer == null)
1193                                 throw new ArgumentNullException ("buffer");
1194
1195                         if (offset < 0)
1196                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1197
1198                         if (size < 0)
1199                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1200
1201                         if (offset + size > buffer.Length)
1202                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1203
1204                         SocketAsyncResult req;
1205                         lock (writeQ) 
1206                         {
1207                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
1208                                 req.Buffer = buffer;
1209                                 req.Offset = offset;
1210                                 req.Size = size;
1211                                 req.SockFlags = socket_flags;
1212                                 writeQ.Enqueue (req);
1213                                 if (writeQ.Count == 1) 
1214                                 {
1215                                         Worker worker = new Worker (req);
1216                                         SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1217                                         sac.BeginInvoke (null, req);
1218                                 }
1219                         }
1220                         return req;
1221                 }
1222
1223                 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1224                         int size,
1225                         SocketFlags socket_flags,
1226                         EndPoint remote_end,
1227                         AsyncCallback callback,
1228                         object state) 
1229                 {
1230                         EnsureStillUsable();
1231
1232                         if (buffer == null)
1233                                 throw new ArgumentNullException ("buffer");
1234
1235                         if (offset < 0)
1236                                 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1237
1238                         if (size < 0)
1239                                 throw new ArgumentOutOfRangeException ("size must be >= 0");
1240
1241                         if (offset + size > buffer.Length)
1242                                 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1243
1244                         SocketAsyncResult req;
1245                         lock (writeQ) 
1246                         {
1247                                 req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1248                                 req.Buffer = buffer;
1249                                 req.Offset = offset;
1250                                 req.Size = size;
1251                                 req.SockFlags = socket_flags;
1252                                 req.EndPoint = remote_end;
1253                                 writeQ.Enqueue (req);
1254                                 if (writeQ.Count == 1) 
1255                                 {
1256                                         Worker worker = new Worker (req);
1257                                         SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1258                                         sac.BeginInvoke (null, req);
1259                                 }
1260                         }
1261                         return req;
1262                 }
1263
1264 #if !TARGET_JVM
1265                 // Creates a new system socket, returning the handle
1266                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1267                 private extern static void Bind_internal(IntPtr sock,
1268                                                          SocketAddress sa,
1269                                                          out int error);
1270
1271                 public void Bind(EndPoint local_end) 
1272                 {
1273                         if (disposed && closed)
1274                                 throw new ObjectDisposedException (GetType ().ToString ());
1275
1276                         if(local_end==null) {
1277                                 throw new ArgumentNullException("local_end");
1278                         }
1279                         
1280                         int error;
1281                         
1282                         Bind_internal(socket, local_end.Serialize(),
1283                                       out error);
1284
1285                         if (error != 0) {
1286                                 throw new SocketException (error);
1287                         }
1288                 }
1289 #else
1290                 private void Bind_internal(GHSocket sock,
1291                         EndPoint sa,
1292                         out int error)
1293                 {
1294                         sock.Bind_internal(sa, out error);
1295                 }
1296
1297                 public void Bind(EndPoint local_end) 
1298                 {
1299                         EnsureStillUsable();
1300
1301                         if(local_end==null) {
1302                                 throw new ArgumentNullException("local_end");
1303                         }
1304                         
1305                         int error;
1306                         
1307                         Bind_internal(socket, local_end,
1308                                       out error);
1309
1310                         if (error != 0) {
1311                                 throw new SocketException (error);
1312                         }
1313                 }
1314 #endif
1315
1316 #if !TARGET_JVM
1317                 // Closes the socket
1318                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1319                 private extern static void Close_internal(IntPtr socket,
1320                                                           out int error);
1321 #else
1322                 private void Close_internal(GHSocket socket, out int error)
1323                 {
1324                         socket.Close_internal(out error);
1325                 }
1326 #endif  
1327
1328                 public void Close() 
1329                 {
1330                         ((IDisposable) this).Dispose ();
1331                 }
1332
1333 #if !TARGET_JVM
1334                 // Connects to the remote address
1335                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1336                 private extern static void Connect_internal(IntPtr sock,
1337                                                             SocketAddress sa,
1338                                                             out int error);
1339 #else
1340                 private void Connect_internal(GHSocket sock,
1341                         EndPoint sa,
1342                         out int error)
1343                 {
1344                         sock.Connect_internal(sa, out error);
1345                 }
1346 #endif
1347
1348                 public void Connect(EndPoint remote_end) 
1349                 {
1350                         EnsureStillUsable();
1351
1352                         if(remote_end==null) {
1353                                 throw new ArgumentNullException("remote_end");
1354                         }
1355
1356                         if (remote_end is IPEndPoint) {
1357                                 IPEndPoint ep = (IPEndPoint) remote_end;
1358                                 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
1359                                         throw new SocketException (10049);
1360                         }
1361
1362                         int error = 0;
1363
1364 #if !TARGET_JVM
1365                                 Connect_internal (socket, remote_end.Serialize(), out error);
1366 #else
1367                                 Connect_internal (socket, remote_end, out error);
1368 #endif
1369                         if (error != 0) {
1370                                 throw new SocketException (error);
1371                         }
1372                         
1373                         connected=true;
1374                 }       
1375         
1376 #if TARGET_JVM
1377                 public void ChangeToSSL()
1378                 {
1379                         try
1380                         {
1381                                 GHSocket tmp = socket.ChangeToSSL(null);
1382                                 if (tmp != null)
1383                                 {
1384                                         socket = tmp;
1385                                 }
1386                         }
1387                         catch (Exception e)
1388                         {
1389 #if DEBUG 
1390                                 Console.WriteLine("Caught exception during ChangeToSSL: {0}, {1}", e.GetType(), e.Message);
1391 #endif
1392                                 throw new SocketException(10045);
1393                         }
1394                 }
1395 #endif          
1396                 
1397                 public Socket EndAccept(IAsyncResult result) 
1398                 {
1399                         EnsureStillUsable();
1400
1401                         if (result == null)
1402                                 throw new ArgumentNullException ("result");
1403
1404                         SocketAsyncResult req = result as SocketAsyncResult;
1405                         if (req == null)
1406                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1407
1408                         if (!result.IsCompleted)
1409                                 result.AsyncWaitHandle.WaitOne();
1410
1411                         req.CheckIfThrowDelayedException();
1412                         return req.Socket;
1413                 }
1414
1415                 public void EndConnect(IAsyncResult result) {
1416                         EnsureStillUsable();
1417
1418                         if (result == null)
1419                                 throw new ArgumentNullException ("result");
1420
1421                         SocketAsyncResult req = result as SocketAsyncResult;
1422                         if (req == null)
1423                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1424
1425                         if (!result.IsCompleted)
1426                                 result.AsyncWaitHandle.WaitOne();
1427
1428                         req.CheckIfThrowDelayedException();
1429                 }
1430
1431 #if NET_2_0
1432                 [MonoNotSupported ("")]
1433                 public void EndDisconnect (IAsyncResult asyncResult)
1434                 {
1435                         throw new NotImplementedException ();
1436                 }
1437 #endif
1438
1439                 public int EndReceive(IAsyncResult result) {
1440                         EnsureStillUsable();
1441
1442                         if (result == null)
1443                                 throw new ArgumentNullException ("result");
1444
1445                         SocketAsyncResult req = result as SocketAsyncResult;
1446                         if (req == null)
1447                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1448
1449                         if (!result.IsCompleted)
1450                                 result.AsyncWaitHandle.WaitOne();
1451
1452                         req.CheckIfThrowDelayedException();
1453                         return req.Total;
1454                 }
1455
1456                 public int EndReceiveFrom(IAsyncResult result,
1457                                           ref EndPoint end_point) 
1458         {
1459                         EnsureStillUsable();
1460
1461                         if (result == null)
1462                                 throw new ArgumentNullException ("result");
1463
1464                         SocketAsyncResult req = result as SocketAsyncResult;
1465                         if (req == null)
1466                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1467
1468                         if (!result.IsCompleted)
1469                                 result.AsyncWaitHandle.WaitOne();
1470
1471                         req.CheckIfThrowDelayedException();
1472                         end_point = req.EndPoint;
1473                         return req.Total;
1474                 }
1475
1476                 public int EndSend(IAsyncResult result) {
1477                         EnsureStillUsable();
1478
1479                         if (result == null)
1480                                 throw new ArgumentNullException ("result");
1481
1482                         SocketAsyncResult req = result as SocketAsyncResult;
1483                         if (req == null)
1484                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1485
1486                         if (!result.IsCompleted)
1487                                 result.AsyncWaitHandle.WaitOne();
1488
1489                         req.CheckIfThrowDelayedException();
1490                         return req.Total;
1491                 }
1492
1493                 public int EndSendTo(IAsyncResult result) {
1494                         EnsureStillUsable();
1495
1496                         if (result == null)
1497                                 throw new ArgumentNullException ("result");
1498
1499                         SocketAsyncResult req = result as SocketAsyncResult;
1500                         if (req == null)
1501                                 throw new ArgumentException ("Invalid IAsyncResult", "result");
1502
1503                         if (!result.IsCompleted)
1504                                 result.AsyncWaitHandle.WaitOne();
1505
1506                         req.CheckIfThrowDelayedException();
1507                         return req.Total;
1508                 }
1509
1510 #if !TARGET_JVM
1511                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1512                 private extern static void GetSocketOption_obj_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, out object obj_val, out int error);
1513                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1514                 private extern static void GetSocketOption_arr_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val, out int error);
1515 #else
1516                 private void GetSocketOption_obj_internal(GHSocket socket, SocketOptionLevel level, 
1517                         SocketOptionName name, out object obj_val, out int error)
1518                 {
1519                         EnsureStillUsable();
1520
1521             socket.GetSocketOption_obj_internal(level, name, out obj_val, out error);
1522                 }
1523                 private void GetSocketOption_arr_internal(GHSocket socket, SocketOptionLevel level, 
1524                         SocketOptionName name, ref byte[] byte_val, out int error)
1525                 {
1526                         EnsureStillUsable();
1527
1528             socket.GetSocketOption_arr_internal(level, name, ref byte_val, out error);
1529                 }
1530 #endif
1531
1532                 public object GetSocketOption(SocketOptionLevel level,
1533                                               SocketOptionName name) {
1534                         object obj_val;
1535                         int error;
1536                         
1537                         GetSocketOption_obj_internal(socket, level, name,
1538                                                      out obj_val, out error);
1539
1540                         if (error != 0) {
1541                                 throw new SocketException (error);
1542                         }
1543                         
1544                         if(name==SocketOptionName.Linger) {
1545                                 return((LingerOption)obj_val);
1546                         } else if (name==SocketOptionName.AddMembership ||
1547                                    name==SocketOptionName.DropMembership) {
1548                                 return((MulticastOption)obj_val);
1549                         } else if (obj_val is int) {
1550                                 return((int)obj_val);
1551                         } else {
1552                                 return(obj_val);
1553                         }
1554                 }
1555
1556                 public void GetSocketOption(SocketOptionLevel level,
1557                                             SocketOptionName name,
1558                                             byte[] opt_value) {
1559                         int error;
1560                         
1561                         GetSocketOption_arr_internal(socket, level, name,
1562                                                      ref opt_value, out error);
1563
1564                         if (error != 0) {
1565                                 throw new SocketException (error);
1566                         }
1567                 }
1568
1569                 public byte[] GetSocketOption(SocketOptionLevel level,
1570                                               SocketOptionName name,
1571                                               int length) {
1572                         byte[] byte_val=new byte[length];
1573                         int error;
1574                         
1575                         GetSocketOption_arr_internal(socket, level, name,
1576                                                      ref byte_val, out error);
1577
1578                         if (error != 0) {
1579                                 throw new SocketException (error);
1580                         }
1581
1582                         return(byte_val);
1583                 }
1584
1585 #if !TARGET_JVM
1586                 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1587                 // common options between UNIX and Winsock are FIONREAD,
1588                 // FIONBIO and SIOCATMARK. Anything else will depend on the
1589                 // system.
1590                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1591                 extern static int WSAIoctl (IntPtr sock, int ioctl_code,
1592                                             byte [] input, byte [] output,
1593                                             out int error);
1594 #else
1595                 int WSAIoctl (GHSocket sock, int ioctl_code,
1596                         byte [] input, byte [] output,
1597                         out int error)
1598                 {
1599                         return sock.WSAIoctl(ioctl_code, input, output, out error);
1600                 }
1601 #endif
1602
1603                 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1604                 {
1605                         if (disposed)
1606                                 throw new ObjectDisposedException (GetType ().ToString ());
1607
1608                         int error;
1609                         int result = WSAIoctl (socket, ioctl_code, in_value,
1610                                                out_value, out error);
1611
1612                         if (error != 0) {
1613                                 throw new SocketException (error);
1614                         }
1615                         
1616                         if (result == -1)
1617                                 throw new InvalidOperationException ("Must use Blocking property instead.");
1618
1619                         return result;
1620                 }
1621
1622 #if NET_2_0
1623                 [MonoNotSupported ("")]
1624                 public int IOControl (IOControlCode ioControlCode, byte [] optionInValue, byte [] optionOutValue)
1625                 {
1626                         throw new NotImplementedException ();
1627                 }
1628 #endif
1629
1630 #if !TARGET_JVM
1631                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1632                 private extern static void Listen_internal(IntPtr sock,
1633                                                            int backlog,
1634                                                            out int error);
1635 #else
1636                 private void Listen_internal(GHSocket sock,
1637                         int backlog,
1638                         out int error)
1639                 {
1640                         EnsureStillUsable();
1641
1642                         sock.Listen_internal(backlog, out error);
1643                 }
1644 #endif
1645
1646                 public void Listen(int backlog) 
1647                 {
1648                         int error;
1649                         
1650                         Listen_internal(socket, backlog, out error);
1651
1652                         if (error != 0) {
1653                                 throw new SocketException (error);
1654                         }
1655                 }
1656
1657 #if !TARGET_JVM
1658                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1659                 extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
1660 #else
1661                 bool Poll_internal (GHSocket socket, SelectMode mode, int timeout, out int error)
1662                 {
1663                         return socket.Poll_internal(mode, timeout, this, out error);
1664                 }
1665 #endif
1666
1667                 public bool Poll(int time_us, SelectMode mode) 
1668                 {
1669                         EnsureStillUsable();
1670
1671                         if (mode != SelectMode.SelectRead &&
1672                             mode != SelectMode.SelectWrite &&
1673                             mode != SelectMode.SelectError)
1674                                 throw new NotSupportedException ("'mode' parameter is not valid.");
1675
1676                         int error;
1677                         bool result = Poll_internal (socket, mode, time_us, out error);
1678                         if (error != 0)
1679                                 throw new SocketException (error);
1680                         
1681                         if (result == true) {
1682                                 /* Update the connected state; for
1683                                  * non-blocking Connect()s this is
1684                                  * when we can find out that the
1685                                  * connect succeeded.
1686                                  */
1687                                 connected = true;
1688                         }
1689
1690                         return result;
1691                 }
1692                 
1693                 public int Receive (byte [] buf)
1694                 {
1695                         EnsureStillUsable();
1696
1697                         if (buf == null)
1698                                 throw new ArgumentNullException ("buf");
1699
1700                         return Receive_nochecks (buf, 0, buf.Length, SocketFlags.None);
1701                 }
1702
1703                 public int Receive (byte [] buf, SocketFlags flags)
1704                 {
1705                         EnsureStillUsable();
1706
1707                         if (buf == null)
1708                                 throw new ArgumentNullException ("buf");
1709
1710                         return Receive_nochecks (buf, 0, buf.Length, flags);
1711                 }
1712
1713                 public int Receive (byte [] buf, int size, SocketFlags flags)
1714                 {
1715                         EnsureStillUsable();
1716
1717                         if (buf == null)
1718                                 throw new ArgumentNullException ("buf");
1719
1720                         if (size < 0 || size > buf.Length)
1721                                 throw new ArgumentOutOfRangeException ("size");
1722
1723                         return Receive_nochecks (buf, 0, size, flags);
1724                 }
1725
1726 #if !TARGET_JVM
1727                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1728                 private extern static int Receive_internal(IntPtr sock,
1729                                                            byte[] buffer,
1730                                                            int offset,
1731                                                            int count,
1732                                                            SocketFlags flags,
1733                                                            out int error);
1734 #else
1735                 private int Receive_internal(GHSocket sock,
1736                         byte[] buffer,
1737                         int offset,
1738                         int count,
1739                         SocketFlags flags,
1740                         out int error)
1741                 {
1742                         return sock.Receive_internal(buffer, offset, count, flags, out error);
1743                 }
1744 #endif
1745
1746                 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
1747                 {
1748                         EnsureStillUsable();
1749
1750                         if(buf==null) 
1751                                 throw new ArgumentNullException ("buf");
1752
1753                         if (offset < 0 || offset > buf.Length)
1754                                 throw new ArgumentOutOfRangeException ("offset");
1755
1756                         if (size < 0 || offset + size > buf.Length)
1757                                 throw new ArgumentOutOfRangeException ("size");
1758
1759                         return Receive_nochecks (buf, offset, size, flags);
1760                 }
1761                         
1762                 int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
1763                 {
1764                         int ret, error;
1765                         ret = Receive_internal (socket, buf, offset, size, flags, out error);
1766
1767                         if(error != 0) {
1768                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1769                                 connected=false;
1770
1771                                 throw new SocketException (error);
1772                         }
1773                         
1774                         connected=true;
1775
1776                         return ret;
1777                 }
1778
1779                 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
1780                 {
1781                         if (buf == null)
1782                                 throw new ArgumentNullException ("buf");
1783
1784                         if (remote_end == null)
1785                                 throw new ArgumentNullException ("remote_end");
1786
1787                         return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
1788                 }
1789
1790                 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
1791                 {
1792                         if (buf == null)
1793                                 throw new ArgumentNullException ("buf");
1794
1795                         if (remote_end == null)
1796                                 throw new ArgumentNullException ("remote_end");
1797
1798
1799                         return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
1800                 }
1801
1802                 public int ReceiveFrom(byte[] buf, int size, SocketFlags flags,
1803                                         ref EndPoint remote_end)
1804                 {
1805                         if (buf == null)
1806                                 throw new ArgumentNullException ("buf");
1807
1808                         if (remote_end == null)
1809                                 throw new ArgumentNullException ("remote_end");
1810
1811                         if (size < 0 || size > buf.Length)
1812                                 throw new ArgumentOutOfRangeException ("size");
1813
1814                         return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
1815                 }
1816
1817 #if !TARGET_JVM
1818                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1819                 private extern static int RecvFrom_internal(IntPtr sock,
1820                                                             byte[] buffer,
1821                                                             int offset,
1822                                                             int count,
1823                                                             SocketFlags flags,
1824                                                             ref SocketAddress sockaddr,
1825                                                             out int error);
1826 #else
1827                 private int RecvFrom_internal(GHSocket sock,
1828                         byte[] buffer,
1829                         int offset,
1830                         int count,
1831                         SocketFlags flags,
1832                         ref SocketAddress sockaddr,
1833                         out int error)
1834                 {
1835                         return sock.RecvFrom_internal(buffer, offset, count, flags, ref sockaddr, out error);
1836                 }
1837
1838 #endif
1839
1840                 public int ReceiveFrom(byte[] buf, int offset, int size, SocketFlags flags,
1841                                        ref EndPoint remote_end) 
1842                 {
1843                         EnsureStillUsable();
1844
1845                         if (buf == null)
1846                                 throw new ArgumentNullException ("buf");
1847
1848                         if (remote_end == null)
1849                                 throw new ArgumentNullException ("remote_end");
1850
1851                         if (offset < 0 || offset > buf.Length)
1852                                 throw new ArgumentOutOfRangeException ("offset");
1853
1854                         if (size < 0 || offset + size > buf.Length)
1855                                 throw new ArgumentOutOfRangeException ("size");
1856
1857                         return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
1858                 }
1859
1860                 int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1861                                           ref EndPoint remote_end)
1862                 {
1863                         EnsureStillUsable();
1864
1865                         SocketAddress sockaddr=remote_end.Serialize();
1866                         int cnt, error;
1867
1868                         cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1869
1870                         if (error != 0) {
1871                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1872                                 connected=false;
1873
1874                                 throw new SocketException (error);
1875                         }
1876
1877                         connected=true;
1878                         
1879                         // If sockaddr is null then we're a connection
1880                         // oriented protocol and should ignore the
1881                         // remote_end parameter (see MSDN
1882                         // documentation for Socket.ReceiveFrom(...) )
1883                         
1884                         if ( sockaddr != null ) {
1885                         // Stupidly, EndPoint.Create() is an
1886                         // instance method
1887                         remote_end=remote_end.Create(sockaddr);
1888                         }
1889
1890                         return cnt;
1891                 }
1892
1893                 public int Send (byte [] buf)
1894                 {
1895                     EnsureStillUsable();
1896
1897                     if (buf == null)
1898                                 throw new ArgumentNullException ("buf");
1899
1900                     return Send_nochecks (buf, 0, buf.Length, SocketFlags.None);
1901                 }
1902
1903                 public int Send (byte [] buf, SocketFlags flags)
1904                 {
1905                     EnsureStillUsable();
1906
1907                     if (buf == null)
1908                                 throw new ArgumentNullException ("buf");
1909
1910                     return Send_nochecks (buf, 0, buf.Length, flags);
1911                 }
1912
1913                 public int Send (byte [] buf, int size, SocketFlags flags)
1914                 {
1915                         EnsureStillUsable();
1916
1917                         if (buf == null)
1918                                 throw new ArgumentNullException ("buf");
1919
1920                         if (size < 0 || size > buf.Length)
1921                                 throw new ArgumentOutOfRangeException ("size");
1922
1923                         return Send_nochecks (buf, 0, size, flags);
1924                 }
1925
1926 #if NET_2_0
1927                 [MonoNotSupported ("")]
1928                 public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1929                 {
1930                         throw new NotImplementedException ();
1931                 }
1932
1933                 [MonoNotSupported ("")]
1934                 public int Send (IList<ArraySegment<byte>> buffers)
1935                 {
1936                         throw new NotImplementedException ();
1937                 }
1938
1939                 [MonoNotSupported ("")]
1940                 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1941                 {
1942                         throw new NotImplementedException ();
1943                 }
1944
1945                 //[CLSCompliantAttribute (false)]
1946                 [MonoNotSupported ("")]
1947                 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1948                 {
1949                         throw new NotImplementedException ();
1950                 }
1951
1952                 [MonoNotSupported ("")]
1953                 public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1954                 {
1955                         throw new NotImplementedException ();
1956                 }
1957
1958                 [MonoNotSupported ("")]
1959                 public int Receive (IList<ArraySegment<byte>> buffers)
1960                 {
1961                         throw new NotImplementedException ();
1962                 }
1963
1964                 //[CLSCompliantAttribute (false)]
1965                 [MonoNotSupported ("")]
1966                 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1967                 {
1968                         throw new NotImplementedException ();
1969                 }
1970
1971                 //[CLSCompliantAttribute (false)]
1972                 [MonoNotSupported ("")]
1973                 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1974                 {
1975                         throw new NotImplementedException ();
1976                 }
1977
1978                 [MonoNotSupported ("")]
1979                 public int ReceiveMessageFrom (byte [] buffer, int offset, int size, ref SocketFlags socketFlags, ref EndPoint remoteEP, out IPPacketInformation ipPacketInformation)
1980                 {
1981                         throw new NotImplementedException ();
1982                 }
1983
1984                 [MonoNotSupported ("")]
1985                 public IAsyncResult BeginReceiveMessageFrom (byte [] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, Object state)
1986                 {
1987                         throw new NotImplementedException ();
1988                 }
1989
1990                 [MonoNotSupported ("")]
1991                 public int EndReceiveMessageFrom (IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation)
1992                 {
1993                         throw new NotImplementedException ();
1994                 }
1995 #endif
1996
1997 #if !TARGET_JVM
1998                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1999                 private extern static int Send_internal(IntPtr sock,
2000                                                         byte[] buf, int offset,
2001                                                         int count,
2002                                                         SocketFlags flags,
2003                                                         out int error);
2004 #else
2005                 private int Send_internal(GHSocket sock,
2006                         byte[] buf, int offset,
2007                         int count,
2008                         SocketFlags flags,
2009                         out int error)
2010                 {
2011                         return sock.Send_internal(buf, offset, count, flags, out error);
2012                 }
2013 #endif
2014
2015                 public int Send (byte[] buf, int offset, int size, SocketFlags flags)
2016                 {
2017                         EnsureStillUsable();
2018
2019                         if (buf == null)
2020                                 throw new ArgumentNullException ("buffer");
2021
2022                         if (offset < 0 || offset > buf.Length)
2023                                 throw new ArgumentOutOfRangeException ("offset");
2024
2025                         if (size < 0 || offset + size > buf.Length)
2026                                 throw new ArgumentOutOfRangeException ("size");
2027
2028                         return Send_nochecks (buf, offset, size, flags);
2029                 }
2030
2031                 int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
2032                 {
2033                         if (size == 0)
2034                                 return 0;
2035
2036                         int ret, error;
2037
2038                         ret = Send_internal (socket, buf, offset, size, flags, out error);
2039
2040                         if (error != 0) {
2041                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2042                                     connected = false;
2043
2044                                 throw new SocketException (error);
2045                         }
2046                         connected = true;
2047
2048                         return ret;
2049                 }
2050
2051                 public int SendTo (byte [] buffer, EndPoint remote_end)
2052                 {
2053                         EnsureStillUsable();
2054
2055                         if (buffer == null)
2056                                 throw new ArgumentNullException ("buffer");
2057
2058                         if (remote_end == null)
2059                                 throw new ArgumentNullException ("remote_end");
2060
2061                         return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2062                 }
2063
2064                 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2065                 {
2066                         EnsureStillUsable();
2067
2068                         if (buffer == null)
2069                                 throw new ArgumentNullException ("buffer");
2070
2071                         if (remote_end == null)
2072                                 throw new ArgumentNullException ("remote_end");
2073                                 
2074                         return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2075                 }
2076
2077                 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2078                 {
2079                         EnsureStillUsable();
2080
2081                         if (buffer == null)
2082                                 throw new ArgumentNullException ("buffer");
2083
2084                         if (remote_end == null)
2085                                 throw new ArgumentNullException ("remote_end");
2086
2087                         if (size < 0 || size > buffer.Length)
2088                                 throw new ArgumentOutOfRangeException ("size");
2089
2090                         return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2091                 }
2092
2093 #if !TARGET_JVM
2094                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2095                 private extern static int SendTo_internal(IntPtr sock,
2096                                                           byte[] buffer,
2097                                                           int offset,
2098                                                           int count,
2099                                                           SocketFlags flags,
2100                                                           SocketAddress sa,
2101                                                           out int error);
2102 #else
2103                 private int SendTo_internal(GHSocket sock,
2104                         byte[] buffer,
2105                         int offset,
2106                         int count,
2107                         SocketFlags flags,
2108                         SocketAddress sa,
2109                         out int error)
2110                 {
2111                         return sock.SendTo_internal(buffer, offset, count, flags, sa, out error);
2112                 }
2113 #endif
2114
2115                 public int SendTo(byte[] buffer, int offset, int size, SocketFlags flags, 
2116                            EndPoint remote_end) 
2117                 {
2118                         EnsureStillUsable();
2119
2120                         if (buffer == null)
2121                                 throw new ArgumentNullException ("buffer");
2122
2123                         if (remote_end == null)
2124                                 throw new ArgumentNullException("remote_end");
2125
2126                         if (offset < 0 || offset > buffer.Length)
2127                                 throw new ArgumentOutOfRangeException ("offset");
2128
2129                         if (size < 0 || offset + size > buffer.Length)
2130                                 throw new ArgumentOutOfRangeException ("size");
2131
2132                         return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2133                 }
2134
2135                 int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2136                                    EndPoint remote_end)
2137                 {
2138                         SocketAddress sockaddr=remote_end.Serialize();
2139
2140                         int ret, error;
2141
2142                         ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2143
2144                         if (error != 0) {
2145                                 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2146                                 connected=false;
2147
2148                                 throw new SocketException (error);
2149                         }
2150
2151                         connected=true;
2152
2153                         return ret;
2154                 }
2155
2156 #if !TARGET_JVM
2157                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2158                 private extern static void SetSocketOption_internal (IntPtr socket, SocketOptionLevel level,
2159                                                                      SocketOptionName name, object obj_val,
2160                                                                      byte [] byte_val, int int_val,
2161                                                                      out int error);
2162 #else
2163                 private void SetSocketOption_internal (GHSocket socket, SocketOptionLevel level,
2164                         SocketOptionName name, object obj_val,
2165                         byte [] byte_val, int int_val,
2166                         out int error)
2167                 {
2168                         socket.SetSocketOption_internal(level, name, obj_val, byte_val, int_val, out error);
2169                 }
2170 #endif
2171
2172                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
2173                 {
2174                         EnsureStillUsable();
2175
2176                         int error;
2177                         
2178                         SetSocketOption_internal(socket, level, name, null,
2179                                                  opt_value, 0, out error);
2180
2181                         if (error != 0) {
2182                                 throw new SocketException (error);
2183                         }
2184                 }
2185
2186                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
2187                 {
2188                         EnsureStillUsable();
2189
2190                         int error;
2191                         
2192                         SetSocketOption_internal(socket, level, name, null,
2193                                                  null, opt_value, out error);
2194
2195                         if (error != 0) {
2196                                 throw new SocketException (error);
2197                         }
2198                 }
2199
2200                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
2201                 {
2202
2203                         EnsureStillUsable();
2204
2205                         if(opt_value==null) {
2206                                 throw new ArgumentNullException();
2207                         }
2208                         
2209                         int error;
2210                         /* From MS documentation on SetSocketOption: "For an
2211                          * option with a Boolean data type, specify a nonzero
2212                          * value to enable the option, and a zero value to
2213                          * disable the option."
2214                          * Booleans are only handled in 2.0
2215                          */
2216
2217                         if (opt_value is System.Boolean) {
2218 #if NET_2_0
2219                                 bool bool_val = (bool) opt_value;
2220                                 int int_val = (bool_val) ? 1 : 0;
2221
2222                                 SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
2223 #else
2224                                 throw new ArgumentException ("Use an integer 1 (true) or 0 (false) instead of a boolean.", "opt_value");
2225 #endif
2226                         } else {
2227                                 SetSocketOption_internal (socket, level, name, opt_value, null, 0, out error);
2228                         }
2229
2230                         if (error != 0)
2231                                 throw new SocketException (error);
2232                 }
2233
2234 #if NET_2_0
2235                 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue) {
2236                         EnsureStillUsable();
2237
2238                         int error;
2239                         int int_val = (optionValue) ? 1 : 0;
2240                         SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
2241                         if (error != 0)
2242                                 throw new SocketException (error);
2243                 }
2244 #endif
2245 #if !TARGET_JVM
2246                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2247                 private extern static void Shutdown_internal(IntPtr socket, SocketShutdown how, out int error);
2248 #else
2249                 private void Shutdown_internal(GHSocket socket, SocketShutdown how, out int error)
2250                 {
2251                         socket.Shutdown_internal(how, out error);
2252                 }
2253 #endif
2254
2255                 public void Shutdown(SocketShutdown how) 
2256                 {
2257                         EnsureStillUsable();
2258
2259                         int error;
2260                         
2261                         Shutdown_internal(socket, how, out error);
2262
2263                         if (error != 0) {
2264                                 throw new SocketException (error);
2265                         }
2266                 }
2267
2268 #if !TARGET_JVM
2269                 public override int GetHashCode ()
2270                 { 
2271                         return (int) socket; 
2272                 }
2273 #else
2274                 public override int GetHashCode ()
2275                 { 
2276                         if (socket == null)
2277                                 return -1;
2278
2279                         return socket.GetHashCode(); 
2280                 }
2281 #endif
2282
2283 #if !TARGET_JVM
2284                 protected virtual void Dispose (bool explicitDisposing)
2285                 {
2286                         if (disposed)
2287                                 return;
2288
2289                         disposed = true;
2290                         connected = false;
2291                         if ((int) socket != -1) 
2292                         {
2293                                 int error;
2294                                 closed = true;
2295                                 IntPtr x = socket;
2296                                 socket = (IntPtr) (-1);
2297                                 Close_internal (x, out error);
2298                                 if (blocking_thread != null) 
2299                                 {
2300                                         blocking_thread.Abort ();
2301                                         blocking_thread = null;
2302                                 }
2303
2304                                 if (error != 0)
2305                                         throw new SocketException (error);
2306                         }
2307                 }
2308 #else
2309         private void EnsureStillUsable()
2310         {
2311             if (disposed && closed)
2312                 throw new ObjectDisposedException(this.GetType().ToString());
2313         }
2314         protected virtual void Dispose (bool explicitDisposing)
2315                 {
2316                         if (disposed)
2317                                 return;
2318
2319                         disposed = true;
2320                         connected = false;
2321                         if (socket != null) 
2322                         {
2323                                 int error;
2324                                 closed = true;
2325                                 GHSocket x = socket;
2326                                 socket = null;
2327                                 Close_internal (x, out error);
2328
2329                                 if (error != 0)
2330                                         throw new SocketException (error);
2331                         }
2332                 }
2333 #endif
2334
2335         #region .Net 2.0 properties and methods
2336 #if NET_2_0
2337
2338             #region Properties
2339         [MonoTODO]
2340         public int ReceiveBufferSize
2341         {
2342             get { throw new NotImplementedException(); }
2343             set { throw new NotImplementedException(); }
2344         }
2345
2346         [MonoTODO]
2347         public int SendBufferSize
2348         {
2349             get { throw new NotImplementedException(); }
2350             set { throw new NotImplementedException(); }
2351         }
2352
2353         [MonoTODO]
2354         public bool UseOnlyOverlappedIO
2355         {
2356             get { throw new NotImplementedException(); }
2357             set { throw new NotImplementedException(); }
2358         }
2359         
2360         [MonoTODO]
2361         public bool NoDelay
2362         {
2363             get { throw new NotImplementedException(); }
2364             set { throw new NotImplementedException(); }
2365         }
2366
2367         [MonoTODO]
2368         public bool IsBound
2369         {
2370             get { throw new NotImplementedException(); }
2371         }
2372
2373         [MonoTODO]
2374         public bool ExclusiveAddressUse
2375         {
2376             get { throw new NotImplementedException(); }
2377             set { throw new NotImplementedException(); }
2378         }
2379
2380         [MonoTODO("udp sockets are not supported")]
2381         public bool DontFragment 
2382         {
2383             get { throw new NotImplementedException(); }
2384             set { throw new NotImplementedException(); }
2385         }
2386
2387         [MonoTODO]
2388         public bool EnableBroadcast
2389         {
2390             get { throw new NotImplementedException(); }
2391             set { throw new NotImplementedException(); }
2392         }
2393
2394         [MonoTODO]
2395         public bool MulticastLoopback
2396         {
2397             get { throw new NotImplementedException(); }
2398             set { throw new NotImplementedException(); }
2399         }
2400
2401         [MonoTODO]
2402         public short Ttl
2403         {
2404             get { throw new NotImplementedException(); }
2405             set { throw new NotImplementedException(); }
2406         }
2407
2408         [MonoTODO]
2409         public int ReceiveTimeout
2410         {
2411             get { throw new NotImplementedException(); }
2412             set { throw new NotImplementedException(); }
2413         }
2414
2415         [MonoTODO]
2416         public int SendTimeout
2417         {
2418             get { throw new NotImplementedException(); }
2419             set { throw new NotImplementedException(); }
2420         }
2421             
2422             #endregion //Properties
2423
2424             #region Methods
2425
2426         [MonoTODO]
2427         public IAsyncResult BeginConnect(IPAddress address, int port,
2428                                         AsyncCallback requestCallback,
2429                                         object state)
2430         {
2431             throw new NotImplementedException();
2432         }
2433
2434         [MonoTODO]
2435         public IAsyncResult BeginConnect(IPAddress[] addresses, int port,
2436                                         AsyncCallback requestCallback,
2437                                         object state)
2438         {
2439             throw new NotImplementedException();
2440         }
2441
2442         [MonoTODO]
2443         public IAsyncResult BeginConnect(string host, int port,
2444                                         AsyncCallback requestCallback,
2445                                         object state)
2446         {
2447             throw new NotImplementedException();
2448         }
2449
2450         [MonoTODO]
2451         public IAsyncResult BeginAccept(int receiveSize, AsyncCallback callback, object state)
2452         {
2453             throw new NotImplementedException();
2454         }
2455
2456         [MonoTODO]
2457         public IAsyncResult BeginAccept( Socket acceptSocket,int receiveSize,
2458                                         AsyncCallback callback, object state)
2459         {
2460             throw new NotImplementedException();
2461         }
2462
2463                 [MonoNotSupported ("")]
2464                 public Socket EndAccept (out byte [] buffer, IAsyncResult asyncResult)
2465                 {
2466                         throw new NotImplementedException ();
2467                 }
2468
2469                 [MonoNotSupported ("")]
2470                 public Socket EndAccept (out byte [] buffer, out int bytesTransferred, IAsyncResult asyncResult)
2471                 {
2472                         throw new NotImplementedException ();
2473                 }
2474
2475         [MonoTODO]
2476         public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state)
2477         {
2478             throw new NotImplementedException();
2479         }
2480
2481                 [MonoNotSupported ("")]
2482                 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, object state)
2483                 {
2484                         throw new NotImplementedException ();
2485                 }
2486
2487                 [MonoNotSupported ("")]
2488                 [CLSCompliantAttribute (false)]
2489                 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, 
2490                                                                                 out SocketError errorCode, AsyncCallback callback, 
2491                                                                                 object state)
2492                 {
2493                         throw new NotImplementedException ();
2494                 }
2495
2496         [MonoTODO]
2497         public IAsyncResult BeginSend(byte[] buffer, int offset, int size,
2498                                         SocketFlags socketFlags, out SocketError errorCode,
2499                                         AsyncCallback callback, object state)
2500         {
2501             throw new NotImplementedException();
2502         }
2503
2504                 [MonoNotSupported ("")]
2505                 public int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2506                 {
2507                         throw new NotImplementedException ();
2508                 }
2509
2510                 [MonoNotSupported ("")]
2511                 public IAsyncResult BeginReceive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2512                 {
2513                         throw new NotImplementedException ();
2514                 }
2515
2516                 [CLSCompliantAttribute (false)]
2517                 [MonoNotSupported ("")]
2518                 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, Object state)
2519                 {
2520                         throw new NotImplementedException ();
2521                 }
2522
2523                 [CLSCompliantAttribute (false)]
2524                 [MonoNotSupported ("")]
2525                 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2526                 {
2527                         throw new NotImplementedException ();
2528                 }
2529
2530                 [MonoNotSupported ("")]
2531                 public int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2532                 {
2533                         throw new NotImplementedException ();
2534                 }
2535
2536                 [MonoNotSupported ("")]
2537                 public void SendFile (string fileName)
2538                 {
2539                         throw new NotImplementedException ();
2540                 }
2541
2542                 [MonoNotSupported ("")]
2543                 public void SendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags)
2544                 {
2545                         throw new NotImplementedException ();
2546                 }
2547
2548                 [MonoNotSupported ("")]
2549                 public IAsyncResult BeginSendFile (string fileName, AsyncCallback callback, object state)
2550                 {
2551                         throw new NotImplementedException ();
2552                 }
2553
2554                 [MonoNotSupported ("")]
2555                 public IAsyncResult BeginSendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags, AsyncCallback callback, object state)
2556                 {
2557                         throw new NotImplementedException ();
2558                 }
2559
2560                 [MonoNotSupported ("")]
2561                 public void EndSendFile (IAsyncResult asyncResult)
2562                 {
2563                         throw new NotImplementedException ();
2564                 }
2565
2566         [MonoTODO]
2567         public void Close(int timeout)
2568         {
2569             throw new NotImplementedException();
2570         }
2571
2572         [MonoTODO]
2573         public void Connect(IPAddress address, int port)
2574         {
2575             throw new NotImplementedException();
2576         }
2577
2578         [MonoTODO]
2579         public void Connect(IPAddress[] address, int port)
2580         {
2581             throw new NotImplementedException();
2582         }
2583
2584         [MonoTODO]
2585         public void Connect(string host, int port)
2586         {
2587             throw new NotImplementedException();
2588         }
2589
2590                 [MonoNotSupported ("")]
2591                 public void Disconnect (bool reuseSocket)
2592                 {
2593                         throw new NotImplementedException ();
2594                 }
2595
2596                 [MonoNotSupported ("")]
2597                 public SocketInformation DuplicateAndClose (int targetProcessId)
2598                 {
2599                         throw new NotImplementedException ();
2600                 }
2601                         #endregion //Methods
2602
2603 #endif
2604         #endregion
2605
2606         void IDisposable.Dispose ()
2607                 {
2608                         Dispose (true);
2609                         GC.SuppressFinalize (this);
2610                 }
2611                 
2612                 ~Socket () {
2613                         Dispose(false);
2614                 }
2615
2616         }
2617 }