move FrameworkName from corlib to System
[mcs.git] / class / System / System.Net.Sockets / Socket.jvm.cs
blobc6eabc50aee3430df3d90fe6325af44da1b8d296
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)
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.
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.Net.Configuration;
37 using System.Runtime.InteropServices;
38 using System.Threading;
40 namespace System.Net.Sockets
42 public class Socket : IDisposable
44 enum SocketOperation
46 Accept,
47 Connect,
48 Receive,
49 ReceiveFrom,
50 Send,
51 SendTo
54 [StructLayout (LayoutKind.Sequential)]
55 private sealed class SocketAsyncResult: IAsyncResult
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;
68 Exception delayedException;
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
76 // Return values
77 Socket acc_socket;
78 int total;
80 bool completed_sync;
81 bool completed;
82 public bool blocking;
83 internal int error;
84 SocketOperation operation;
85 public object ares;
87 public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
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;
98 public void CheckIfThrowDelayedException ()
100 if (delayedException != null)
101 throw delayedException;
103 if (error != 0)
104 throw new SocketException (error);
107 void CompleteAllOnDispose (Queue queue)
109 object [] pending = queue.ToArray ();
110 queue.Clear ();
112 WaitCallback cb;
113 for (int i = 0; i < pending.Length; i++)
115 SocketAsyncResult ares = (SocketAsyncResult) pending [i];
116 cb = new WaitCallback (ares.CompleteDisposed);
117 ThreadPool.QueueUserWorkItem (cb, null);
121 void CompleteDisposed (object unused)
123 Complete ();
126 public void Complete ()
128 if (operation != SocketOperation.Receive && Sock.disposed)
129 delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
131 IsCompleted = true;
133 Queue queue = null;
134 if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom)
136 queue = Sock.readQ;
138 else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo)
140 queue = Sock.writeQ;
143 if (queue != null)
145 SocketAsyncCall sac = null;
146 SocketAsyncResult req = null;
147 lock (queue)
149 queue.Dequeue (); // remove ourselves
150 if (queue.Count > 0)
152 req = (SocketAsyncResult) queue.Peek ();
153 if (!Sock.disposed)
155 Worker worker = new Worker (req);
156 sac = GetDelegate (worker, req.operation);
158 else
160 CompleteAllOnDispose (queue);
165 if (sac != null)
166 sac.BeginInvoke (null, req);
169 if (callback != null)
170 callback (this);
173 SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
175 switch (op)
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
190 public void Complete (bool synch)
192 completed_sync = synch;
193 Complete ();
196 public void Complete (int total)
198 this.total = total;
199 Complete ();
202 public void Complete (Exception e, bool synch)
204 completed_sync = synch;
205 delayedException = e;
206 Complete ();
209 public void Complete (Exception e)
211 delayedException = e;
212 Complete ();
215 public void Complete (Socket s)
217 acc_socket = s;
218 Complete ();
221 public object AsyncState
223 get
225 return state;
229 public WaitHandle AsyncWaitHandle
231 get
233 lock (this)
235 if (waithandle == null)
236 waithandle = new ManualResetEvent (completed);
239 return waithandle;
241 set
243 waithandle=value;
247 public bool CompletedSynchronously
249 get
251 return(completed_sync);
255 public bool IsCompleted
257 get
259 return(completed);
261 set
263 completed=value;
264 lock (this)
266 if (waithandle != null && value)
268 ((ManualResetEvent) waithandle).Set ();
274 public Socket Socket
276 get
278 return acc_socket;
282 public int Total
284 get
286 return total;
288 set
290 total = value;
295 private sealed class Worker
297 SocketAsyncResult result;
299 public Worker (SocketAsyncResult ares)
301 this.result = ares;
304 public void Accept ()
306 Socket acc_socket = null;
307 try
309 acc_socket = result.Sock.Accept ();
311 catch (Exception e)
313 result.Complete (e);
314 return;
317 result.Complete (acc_socket);
320 public void Connect ()
322 try
324 result.Sock.Connect (result.EndPoint);
325 result.Sock.connected = true;
327 catch (Exception e)
329 result.Complete (e);
330 return;
333 result.Complete ();
336 #if !TARGET_JVM
337 public void Receive ()
339 // Actual recv() done in the runtime
340 result.Complete ();
342 #else
343 public void Receive ()
345 int total = 0;
346 try
348 total = result.Sock.Receive_nochecks (result.Buffer,
349 result.Offset,
350 result.Size,
351 result.SockFlags);
353 catch (Exception e)
355 result.Complete (e);
356 return;
359 result.Complete (total);
361 #endif
363 public void ReceiveFrom ()
365 int total = 0;
366 try
368 total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
369 result.Offset,
370 result.Size,
371 result.SockFlags,
372 ref result.EndPoint);
374 catch (Exception e)
376 result.Complete (e);
377 return;
380 result.Complete (total);
383 int send_so_far;
385 void UpdateSendValues (int last_sent)
387 if (result.error == 0)
389 send_so_far += last_sent;
390 result.Offset += last_sent;
391 result.Size -= last_sent;
395 #if !TARGET_JVM
396 public void Send ()
398 // Actual send() done in the runtime
399 if (result.error == 0)
401 UpdateSendValues (result.Total);
402 if (result.Sock.disposed)
404 result.Complete ();
405 return;
408 if (result.Size > 0)
410 SocketAsyncCall sac = new SocketAsyncCall (this.Send);
411 sac.BeginInvoke (null, result);
412 return; // Have to finish writing everything. See bug #74475.
414 result.Total = send_so_far;
416 result.Complete ();
418 #else
419 public void Send ()
421 int total = 0;
422 try
424 total = result.Sock.Send_nochecks (result.Buffer,
425 result.Offset,
426 result.Size,
427 result.SockFlags);
429 UpdateSendValues (total);
430 if (result.Size > 0)
432 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
433 sac.BeginInvoke (null, result);
434 return; // Have to finish writing everything. See bug #74475.
436 result.Total = send_so_far;
438 catch (Exception e)
440 result.Complete (e);
441 return;
444 result.Complete ();
446 #endif
448 public void SendTo ()
450 int total = 0;
451 try
453 total = result.Sock.SendTo_nochecks (result.Buffer,
454 result.Offset,
455 result.Size,
456 result.SockFlags,
457 result.EndPoint);
459 UpdateSendValues (total);
460 if (result.Size > 0)
462 SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
463 sac.BeginInvoke (null, result);
464 return; // Have to finish writing everything. See bug #74475.
466 result.Total = send_so_far;
468 catch (Exception e)
470 result.Complete (e);
471 return;
474 result.Complete ();
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);
493 delegate void SocketAsyncCall ();
495 * These two fields are looked up by name by the runtime, don't change
496 * their name without also updating the runtime code.
498 private static int ipv4Supported = -1, ipv6Supported = -1;
500 /* When true, the socket was connected at the time of
501 * the last IO operation
503 private bool connected=false;
504 /* true if we called Close_internal */
505 private bool closed;
506 internal bool disposed;
508 /* Used in LocalEndPoint and RemoteEndPoint if the
509 * Mono.Posix assembly is available
511 private static object unixendpoint=null;
512 private static Type unixendpointtype=null;
514 static void AddSockets (ArrayList sockets, IList list, string name)
516 if (list != null)
518 foreach (Socket sock in list)
520 if (sock == null) // MS throws a NullRef
521 throw new ArgumentNullException (name, "Contains a null element");
522 sockets.Add (sock);
526 sockets.Add (null);
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)
537 GHSocketFactory.Select_internal(ref sockets, microSeconds, out error);
539 #endif
541 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
543 ArrayList list = new ArrayList ();
544 AddSockets (list, checkRead, "checkRead");
545 AddSockets (list, checkWrite, "checkWrite");
546 AddSockets (list, checkError, "checkError");
548 if (list.Count == 3)
550 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
551 "All the lists are null or empty.");
554 int error;
556 * The 'sockets' array contains: READ socket 0-n, null,
557 * WRITE socket 0-n, null,
558 * ERROR socket 0-n, null
560 Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
561 Select_internal (ref sockets, microSeconds, out error);
563 if (error != 0)
564 throw new SocketException (error);
566 if (checkRead != null)
567 checkRead.Clear ();
569 if (checkWrite != null)
570 checkWrite.Clear ();
572 if (checkError != null)
573 checkError.Clear ();
575 if (sockets == null)
576 return;
578 int mode = 0;
579 int count = sockets.Length;
580 IList currentList = checkRead;
581 for (int i = 0; i < count; i++)
583 Socket sock = sockets [i];
584 if (sock == null)
585 { // separator
586 currentList = (mode == 0) ? checkWrite : checkError;
587 mode++;
588 continue;
591 if (currentList != null)
593 sock.connected = true;
594 currentList.Add (sock);
599 #if !TARGET_JVM
600 static Socket()
602 Assembly ass;
604 try {
605 ass = Assembly.Load (Consts.AssemblyMono_Posix);
606 } catch (FileNotFoundException) {
607 return;
610 unixendpointtype=ass.GetType("Mono.Posix.UnixEndPoint");
612 /* The endpoint Create() method is an instance
613 * method :-(
615 Type[] arg_types=new Type[1];
616 arg_types[0]=typeof(string);
617 ConstructorInfo cons=unixendpointtype.GetConstructor(arg_types);
619 object[] args=new object[1];
620 args[0]="";
622 unixendpoint=cons.Invoke(args);
624 #endif
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)
637 #endif
638 address_family=family;
639 socket_type=type;
640 protocol_type=proto;
642 socket=sock;
643 connected=true;
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)
660 return GHSocketFactory.Socket_internal(family, type, proto, out error);
662 #endif
664 public Socket(AddressFamily family, SocketType type,
665 ProtocolType proto)
667 address_family=family;
668 socket_type=type;
669 protocol_type=proto;
670 int error;
672 socket=Socket_internal(family, type, proto, out error);
673 if (error != 0) {
674 throw new SocketException (error);
678 public AddressFamily AddressFamily
680 get
682 return(address_family);
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)
694 return socket.Available_internal(out error);
696 #endif
698 public int Available
700 get
702 EnsureStillUsable();
704 int ret, error;
706 ret = Available_internal(socket, out error);
708 if (error != 0)
710 throw new SocketException (error);
713 return(ret);
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)
725 socket.Blocking_internal(block, out error);
727 #endif
729 public bool Blocking
731 get
733 return(blocking);
735 set
737 EnsureStillUsable();
739 int error;
741 Blocking_internal(socket, value, out error);
743 if (error != 0) {
744 throw new SocketException (error);
747 blocking=value;
751 public bool Connected
753 get
755 return(connected);
759 #if !TARGET_JVM
760 public IntPtr Handle
762 get
764 return(socket);
767 #else
768 public IntPtr Handle
770 get
772 throw new NotImplementedException ();
776 internal GHSocket GHHandle
778 get
780 return socket;
783 #endif
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);
790 [MonoTODO("Support non-IP endpoints")]
791 public EndPoint LocalEndPoint
793 get
795 if (disposed && closed)
796 throw new ObjectDisposedException (GetType ().ToString ());
798 SocketAddress sa;
799 int error;
801 sa=LocalEndPoint_internal(socket, out error);
803 if (error != 0) {
804 throw new SocketException (error);
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();
819 #else
820 private EndPoint LocalEndPoint_internal(GHSocket socket, out int error)
822 return socket.LocalEndPoint_internal(out error);
825 public EndPoint LocalEndPoint
827 get
829 EnsureStillUsable();
831 int error;
833 EndPoint ret = LocalEndPoint_internal(socket, out error);
835 if (error != 0)
837 throw new SocketException (error);
840 return ret;
843 #endif
845 public ProtocolType ProtocolType
847 get
849 return(protocol_type);
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);
858 [MonoTODO("Support non-IP endpoints")]
859 public EndPoint RemoteEndPoint
861 get
863 if (disposed && closed)
864 throw new ObjectDisposedException (GetType ().ToString ());
866 SocketAddress sa;
867 int error;
869 sa=RemoteEndPoint_internal(socket, out error);
871 if (error != 0) {
872 throw new SocketException (error);
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();
887 #else
888 private EndPoint RemoteEndPoint_internal(GHSocket socket, out int error)
890 return socket.RemoteEndPoint_internal(out error);
893 public EndPoint RemoteEndPoint
895 get
897 EnsureStillUsable();
899 int error;
901 EndPoint ret = RemoteEndPoint_internal(socket, out error);
903 if (error != 0)
905 throw new SocketException (error);
908 return ret;
911 #endif
913 public SocketType SocketType
915 get
917 return(socket_type);
921 #if NET_1_1
922 public static bool SupportsIPv4
924 get
926 CheckProtocolSupport();
927 return ipv4Supported == 1;
931 public static bool SupportsIPv6
933 get
935 CheckProtocolSupport();
936 return ipv6Supported == 1;
939 #else
940 internal static bool SupportsIPv4
942 get
944 return true;
948 internal static bool SupportsIPv6
950 get
952 return false;
955 #endif
957 internal static void CheckProtocolSupport()
959 if(ipv4Supported == -1)
961 try
963 Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
964 tmp.Close();
966 ipv4Supported = 1;
968 catch
970 ipv4Supported = 0;
974 if(ipv6Supported == -1)
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");
984 if(config != null)
985 ipv6Supported = config.ipv6Enabled?-1:0;
986 #endif
987 if(ipv6Supported != 0)
989 try
991 Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
992 tmp.Close();
994 ipv6Supported = 1;
996 catch { }
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)
1009 return sock.Accept_internal(out error);
1011 #endif
1013 public Socket Accept()
1015 EnsureStillUsable();
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);
1028 Socket accepted = new Socket(this.AddressFamily,
1029 this.SocketType,
1030 this.ProtocolType, sock);
1032 accepted.Blocking = this.Blocking;
1033 return(accepted);
1036 public IAsyncResult BeginAccept(AsyncCallback callback,
1037 object state)
1040 EnsureStillUsable();
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);
1049 public IAsyncResult BeginConnect(EndPoint end_point,
1050 AsyncCallback callback,
1051 object state)
1054 EnsureStillUsable();
1056 if (end_point == null)
1057 throw new ArgumentNullException ("end_point");
1059 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
1060 req.EndPoint = end_point;
1062 // Bug #75154: Connect() should not succeed for .Any addresses.
1063 if (end_point is IPEndPoint)
1065 IPEndPoint ep = (IPEndPoint) end_point;
1066 if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
1068 req.Complete (new SocketException (10049), true);
1069 return req;
1073 int error = 0;
1074 if (!blocking)
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)
1084 // succeeded synch
1085 connected = true;
1086 req.Complete (true);
1088 else if (error != 10036 && error != 10035)
1090 // error synch
1091 connected = false;
1092 req.Complete (new SocketException (error), true);
1096 if (blocking || error == 10036 || error == 10035)
1098 // continue asynch
1099 connected = false;
1100 Worker worker = new Worker (req);
1101 SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
1102 sac.BeginInvoke (null, req);
1105 return(req);
1108 public IAsyncResult BeginReceive(byte[] buffer, int offset,
1109 int size,
1110 SocketFlags socket_flags,
1111 AsyncCallback callback,
1112 object state)
1115 EnsureStillUsable();
1117 if (buffer == null)
1118 throw new ArgumentNullException ("buffer");
1120 if (offset < 0 || offset > buffer.Length)
1121 throw new ArgumentOutOfRangeException ("offset");
1123 if (size < 0 || offset + size > buffer.Length)
1124 throw new ArgumentOutOfRangeException ("size");
1126 SocketAsyncResult req;
1127 lock (readQ)
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)
1137 Worker worker = new Worker (req);
1138 SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
1139 sac.BeginInvoke (null, req);
1143 return req;
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)
1153 EnsureStillUsable();
1155 if (buffer == null)
1156 throw new ArgumentNullException ("buffer");
1158 if (offset < 0)
1159 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1161 if (size < 0)
1162 throw new ArgumentOutOfRangeException ("size must be >= 0");
1164 if (offset + size > buffer.Length)
1165 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1167 SocketAsyncResult req;
1168 lock (readQ)
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)
1179 Worker worker = new Worker (req);
1180 SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
1181 sac.BeginInvoke (null, req);
1184 return req;
1187 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
1188 AsyncCallback callback, object state)
1190 EnsureStillUsable();
1192 if (buffer == null)
1193 throw new ArgumentNullException ("buffer");
1195 if (offset < 0)
1196 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1198 if (size < 0)
1199 throw new ArgumentOutOfRangeException ("size must be >= 0");
1201 if (offset + size > buffer.Length)
1202 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1204 SocketAsyncResult req;
1205 lock (writeQ)
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)
1215 Worker worker = new Worker (req);
1216 SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
1217 sac.BeginInvoke (null, req);
1220 return req;
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)
1230 EnsureStillUsable();
1232 if (buffer == null)
1233 throw new ArgumentNullException ("buffer");
1235 if (offset < 0)
1236 throw new ArgumentOutOfRangeException ("offset must be >= 0");
1238 if (size < 0)
1239 throw new ArgumentOutOfRangeException ("size must be >= 0");
1241 if (offset + size > buffer.Length)
1242 throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
1244 SocketAsyncResult req;
1245 lock (writeQ)
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)
1256 Worker worker = new Worker (req);
1257 SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
1258 sac.BeginInvoke (null, req);
1261 return req;
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);
1271 public void Bind(EndPoint local_end)
1273 if (disposed && closed)
1274 throw new ObjectDisposedException (GetType ().ToString ());
1276 if(local_end==null) {
1277 throw new ArgumentNullException("local_end");
1280 int error;
1282 Bind_internal(socket, local_end.Serialize(),
1283 out error);
1285 if (error != 0) {
1286 throw new SocketException (error);
1289 #else
1290 private void Bind_internal(GHSocket sock,
1291 EndPoint sa,
1292 out int error)
1294 sock.Bind_internal(sa, out error);
1297 public void Bind(EndPoint local_end)
1299 EnsureStillUsable();
1301 if(local_end==null) {
1302 throw new ArgumentNullException("local_end");
1305 int error;
1307 Bind_internal(socket, local_end,
1308 out error);
1310 if (error != 0) {
1311 throw new SocketException (error);
1314 #endif
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)
1324 socket.Close_internal(out error);
1326 #endif
1328 public void Close()
1330 ((IDisposable) this).Dispose ();
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)
1344 sock.Connect_internal(sa, out error);
1346 #endif
1348 public void Connect(EndPoint remote_end)
1350 EnsureStillUsable();
1352 if(remote_end==null) {
1353 throw new ArgumentNullException("remote_end");
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);
1362 int error = 0;
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);
1373 connected=true;
1376 #if TARGET_JVM
1377 public void ChangeToSSL()
1381 GHSocket tmp = socket.ChangeToSSL(null);
1382 if (tmp != null)
1384 socket = tmp;
1387 catch (Exception e)
1389 #if DEBUG
1390 Console.WriteLine("Caught exception during ChangeToSSL: {0}, {1}", e.GetType(), e.Message);
1391 #endif
1392 throw new SocketException(10045);
1395 #endif
1397 public Socket EndAccept(IAsyncResult result)
1399 EnsureStillUsable();
1401 if (result == null)
1402 throw new ArgumentNullException ("result");
1404 SocketAsyncResult req = result as SocketAsyncResult;
1405 if (req == null)
1406 throw new ArgumentException ("Invalid IAsyncResult", "result");
1408 if (!result.IsCompleted)
1409 result.AsyncWaitHandle.WaitOne();
1411 req.CheckIfThrowDelayedException();
1412 return req.Socket;
1415 public void EndConnect(IAsyncResult result) {
1416 EnsureStillUsable();
1418 if (result == null)
1419 throw new ArgumentNullException ("result");
1421 SocketAsyncResult req = result as SocketAsyncResult;
1422 if (req == null)
1423 throw new ArgumentException ("Invalid IAsyncResult", "result");
1425 if (!result.IsCompleted)
1426 result.AsyncWaitHandle.WaitOne();
1428 req.CheckIfThrowDelayedException();
1431 #if NET_2_0
1432 [MonoNotSupported ("")]
1433 public void EndDisconnect (IAsyncResult asyncResult)
1435 throw new NotImplementedException ();
1437 #endif
1439 public int EndReceive(IAsyncResult result) {
1440 EnsureStillUsable();
1442 if (result == null)
1443 throw new ArgumentNullException ("result");
1445 SocketAsyncResult req = result as SocketAsyncResult;
1446 if (req == null)
1447 throw new ArgumentException ("Invalid IAsyncResult", "result");
1449 if (!result.IsCompleted)
1450 result.AsyncWaitHandle.WaitOne();
1452 req.CheckIfThrowDelayedException();
1453 return req.Total;
1456 public int EndReceiveFrom(IAsyncResult result,
1457 ref EndPoint end_point)
1459 EnsureStillUsable();
1461 if (result == null)
1462 throw new ArgumentNullException ("result");
1464 SocketAsyncResult req = result as SocketAsyncResult;
1465 if (req == null)
1466 throw new ArgumentException ("Invalid IAsyncResult", "result");
1468 if (!result.IsCompleted)
1469 result.AsyncWaitHandle.WaitOne();
1471 req.CheckIfThrowDelayedException();
1472 end_point = req.EndPoint;
1473 return req.Total;
1476 public int EndSend(IAsyncResult result) {
1477 EnsureStillUsable();
1479 if (result == null)
1480 throw new ArgumentNullException ("result");
1482 SocketAsyncResult req = result as SocketAsyncResult;
1483 if (req == null)
1484 throw new ArgumentException ("Invalid IAsyncResult", "result");
1486 if (!result.IsCompleted)
1487 result.AsyncWaitHandle.WaitOne();
1489 req.CheckIfThrowDelayedException();
1490 return req.Total;
1493 public int EndSendTo(IAsyncResult result) {
1494 EnsureStillUsable();
1496 if (result == null)
1497 throw new ArgumentNullException ("result");
1499 SocketAsyncResult req = result as SocketAsyncResult;
1500 if (req == null)
1501 throw new ArgumentException ("Invalid IAsyncResult", "result");
1503 if (!result.IsCompleted)
1504 result.AsyncWaitHandle.WaitOne();
1506 req.CheckIfThrowDelayedException();
1507 return req.Total;
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)
1519 EnsureStillUsable();
1521 socket.GetSocketOption_obj_internal(level, name, out obj_val, out error);
1523 private void GetSocketOption_arr_internal(GHSocket socket, SocketOptionLevel level,
1524 SocketOptionName name, ref byte[] byte_val, out int error)
1526 EnsureStillUsable();
1528 socket.GetSocketOption_arr_internal(level, name, ref byte_val, out error);
1530 #endif
1532 public object GetSocketOption(SocketOptionLevel level,
1533 SocketOptionName name) {
1534 object obj_val;
1535 int error;
1537 GetSocketOption_obj_internal(socket, level, name,
1538 out obj_val, out error);
1540 if (error != 0) {
1541 throw new SocketException (error);
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);
1556 public void GetSocketOption(SocketOptionLevel level,
1557 SocketOptionName name,
1558 byte[] opt_value) {
1559 int error;
1561 GetSocketOption_arr_internal(socket, level, name,
1562 ref opt_value, out error);
1564 if (error != 0) {
1565 throw new SocketException (error);
1569 public byte[] GetSocketOption(SocketOptionLevel level,
1570 SocketOptionName name,
1571 int length) {
1572 byte[] byte_val=new byte[length];
1573 int error;
1575 GetSocketOption_arr_internal(socket, level, name,
1576 ref byte_val, out error);
1578 if (error != 0) {
1579 throw new SocketException (error);
1582 return(byte_val);
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)
1599 return sock.WSAIoctl(ioctl_code, input, output, out error);
1601 #endif
1603 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1605 if (disposed)
1606 throw new ObjectDisposedException (GetType ().ToString ());
1608 int error;
1609 int result = WSAIoctl (socket, ioctl_code, in_value,
1610 out_value, out error);
1612 if (error != 0) {
1613 throw new SocketException (error);
1616 if (result == -1)
1617 throw new InvalidOperationException ("Must use Blocking property instead.");
1619 return result;
1622 #if NET_2_0
1623 [MonoNotSupported ("")]
1624 public int IOControl (IOControlCode ioControlCode, byte [] optionInValue, byte [] optionOutValue)
1626 throw new NotImplementedException ();
1628 #endif
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)
1640 EnsureStillUsable();
1642 sock.Listen_internal(backlog, out error);
1644 #endif
1646 public void Listen(int backlog)
1648 int error;
1650 Listen_internal(socket, backlog, out error);
1652 if (error != 0) {
1653 throw new SocketException (error);
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)
1663 return socket.Poll_internal(mode, timeout, this, out error);
1665 #endif
1667 public bool Poll(int time_us, SelectMode mode)
1669 EnsureStillUsable();
1671 if (mode != SelectMode.SelectRead &&
1672 mode != SelectMode.SelectWrite &&
1673 mode != SelectMode.SelectError)
1674 throw new NotSupportedException ("'mode' parameter is not valid.");
1676 int error;
1677 bool result = Poll_internal (socket, mode, time_us, out error);
1678 if (error != 0)
1679 throw new SocketException (error);
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.
1687 connected = true;
1690 return result;
1693 public int Receive (byte [] buf)
1695 EnsureStillUsable();
1697 if (buf == null)
1698 throw new ArgumentNullException ("buf");
1700 return Receive_nochecks (buf, 0, buf.Length, SocketFlags.None);
1703 public int Receive (byte [] buf, SocketFlags flags)
1705 EnsureStillUsable();
1707 if (buf == null)
1708 throw new ArgumentNullException ("buf");
1710 return Receive_nochecks (buf, 0, buf.Length, flags);
1713 public int Receive (byte [] buf, int size, SocketFlags flags)
1715 EnsureStillUsable();
1717 if (buf == null)
1718 throw new ArgumentNullException ("buf");
1720 if (size < 0 || size > buf.Length)
1721 throw new ArgumentOutOfRangeException ("size");
1723 return Receive_nochecks (buf, 0, size, flags);
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)
1742 return sock.Receive_internal(buffer, offset, count, flags, out error);
1744 #endif
1746 public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
1748 EnsureStillUsable();
1750 if(buf==null)
1751 throw new ArgumentNullException ("buf");
1753 if (offset < 0 || offset > buf.Length)
1754 throw new ArgumentOutOfRangeException ("offset");
1756 if (size < 0 || offset + size > buf.Length)
1757 throw new ArgumentOutOfRangeException ("size");
1759 return Receive_nochecks (buf, offset, size, flags);
1762 int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
1764 int ret, error;
1765 ret = Receive_internal (socket, buf, offset, size, flags, out error);
1767 if(error != 0) {
1768 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1769 connected=false;
1771 throw new SocketException (error);
1774 connected=true;
1776 return ret;
1779 public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
1781 if (buf == null)
1782 throw new ArgumentNullException ("buf");
1784 if (remote_end == null)
1785 throw new ArgumentNullException ("remote_end");
1787 return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
1790 public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
1792 if (buf == null)
1793 throw new ArgumentNullException ("buf");
1795 if (remote_end == null)
1796 throw new ArgumentNullException ("remote_end");
1799 return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
1802 public int ReceiveFrom(byte[] buf, int size, SocketFlags flags,
1803 ref EndPoint remote_end)
1805 if (buf == null)
1806 throw new ArgumentNullException ("buf");
1808 if (remote_end == null)
1809 throw new ArgumentNullException ("remote_end");
1811 if (size < 0 || size > buf.Length)
1812 throw new ArgumentOutOfRangeException ("size");
1814 return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
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)
1835 return sock.RecvFrom_internal(buffer, offset, count, flags, ref sockaddr, out error);
1838 #endif
1840 public int ReceiveFrom(byte[] buf, int offset, int size, SocketFlags flags,
1841 ref EndPoint remote_end)
1843 EnsureStillUsable();
1845 if (buf == null)
1846 throw new ArgumentNullException ("buf");
1848 if (remote_end == null)
1849 throw new ArgumentNullException ("remote_end");
1851 if (offset < 0 || offset > buf.Length)
1852 throw new ArgumentOutOfRangeException ("offset");
1854 if (size < 0 || offset + size > buf.Length)
1855 throw new ArgumentOutOfRangeException ("size");
1857 return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
1860 int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1861 ref EndPoint remote_end)
1863 EnsureStillUsable();
1865 SocketAddress sockaddr=remote_end.Serialize();
1866 int cnt, error;
1868 cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1870 if (error != 0) {
1871 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
1872 connected=false;
1874 throw new SocketException (error);
1877 connected=true;
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(...) )
1884 if ( sockaddr != null ) {
1885 // Stupidly, EndPoint.Create() is an
1886 // instance method
1887 remote_end=remote_end.Create(sockaddr);
1890 return cnt;
1893 public int Send (byte [] buf)
1895 EnsureStillUsable();
1897 if (buf == null)
1898 throw new ArgumentNullException ("buf");
1900 return Send_nochecks (buf, 0, buf.Length, SocketFlags.None);
1903 public int Send (byte [] buf, SocketFlags flags)
1905 EnsureStillUsable();
1907 if (buf == null)
1908 throw new ArgumentNullException ("buf");
1910 return Send_nochecks (buf, 0, buf.Length, flags);
1913 public int Send (byte [] buf, int size, SocketFlags flags)
1915 EnsureStillUsable();
1917 if (buf == null)
1918 throw new ArgumentNullException ("buf");
1920 if (size < 0 || size > buf.Length)
1921 throw new ArgumentOutOfRangeException ("size");
1923 return Send_nochecks (buf, 0, size, flags);
1926 #if NET_2_0
1927 [MonoNotSupported ("")]
1928 public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1930 throw new NotImplementedException ();
1933 [MonoNotSupported ("")]
1934 public int Send (IList<ArraySegment<byte>> buffers)
1936 throw new NotImplementedException ();
1939 [MonoNotSupported ("")]
1940 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1942 throw new NotImplementedException ();
1945 //[CLSCompliantAttribute (false)]
1946 [MonoNotSupported ("")]
1947 public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1949 throw new NotImplementedException ();
1952 [MonoNotSupported ("")]
1953 public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
1955 throw new NotImplementedException ();
1958 [MonoNotSupported ("")]
1959 public int Receive (IList<ArraySegment<byte>> buffers)
1961 throw new NotImplementedException ();
1964 //[CLSCompliantAttribute (false)]
1965 [MonoNotSupported ("")]
1966 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
1968 throw new NotImplementedException ();
1971 //[CLSCompliantAttribute (false)]
1972 [MonoNotSupported ("")]
1973 public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
1975 throw new NotImplementedException ();
1978 [MonoNotSupported ("")]
1979 public int ReceiveMessageFrom (byte [] buffer, int offset, int size, ref SocketFlags socketFlags, ref EndPoint remoteEP, out IPPacketInformation ipPacketInformation)
1981 throw new NotImplementedException ();
1984 [MonoNotSupported ("")]
1985 public IAsyncResult BeginReceiveMessageFrom (byte [] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, Object state)
1987 throw new NotImplementedException ();
1990 [MonoNotSupported ("")]
1991 public int EndReceiveMessageFrom (IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation)
1993 throw new NotImplementedException ();
1995 #endif
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)
2011 return sock.Send_internal(buf, offset, count, flags, out error);
2013 #endif
2015 public int Send (byte[] buf, int offset, int size, SocketFlags flags)
2017 EnsureStillUsable();
2019 if (buf == null)
2020 throw new ArgumentNullException ("buffer");
2022 if (offset < 0 || offset > buf.Length)
2023 throw new ArgumentOutOfRangeException ("offset");
2025 if (size < 0 || offset + size > buf.Length)
2026 throw new ArgumentOutOfRangeException ("size");
2028 return Send_nochecks (buf, offset, size, flags);
2031 int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
2033 if (size == 0)
2034 return 0;
2036 int ret, error;
2038 ret = Send_internal (socket, buf, offset, size, flags, out error);
2040 if (error != 0) {
2041 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2042 connected = false;
2044 throw new SocketException (error);
2046 connected = true;
2048 return ret;
2051 public int SendTo (byte [] buffer, EndPoint remote_end)
2053 EnsureStillUsable();
2055 if (buffer == null)
2056 throw new ArgumentNullException ("buffer");
2058 if (remote_end == null)
2059 throw new ArgumentNullException ("remote_end");
2061 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2064 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2066 EnsureStillUsable();
2068 if (buffer == null)
2069 throw new ArgumentNullException ("buffer");
2071 if (remote_end == null)
2072 throw new ArgumentNullException ("remote_end");
2074 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2077 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2079 EnsureStillUsable();
2081 if (buffer == null)
2082 throw new ArgumentNullException ("buffer");
2084 if (remote_end == null)
2085 throw new ArgumentNullException ("remote_end");
2087 if (size < 0 || size > buffer.Length)
2088 throw new ArgumentOutOfRangeException ("size");
2090 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
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)
2111 return sock.SendTo_internal(buffer, offset, count, flags, sa, out error);
2113 #endif
2115 public int SendTo(byte[] buffer, int offset, int size, SocketFlags flags,
2116 EndPoint remote_end)
2118 EnsureStillUsable();
2120 if (buffer == null)
2121 throw new ArgumentNullException ("buffer");
2123 if (remote_end == null)
2124 throw new ArgumentNullException("remote_end");
2126 if (offset < 0 || offset > buffer.Length)
2127 throw new ArgumentOutOfRangeException ("offset");
2129 if (size < 0 || offset + size > buffer.Length)
2130 throw new ArgumentOutOfRangeException ("size");
2132 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2135 int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2136 EndPoint remote_end)
2138 SocketAddress sockaddr=remote_end.Serialize();
2140 int ret, error;
2142 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2144 if (error != 0) {
2145 if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
2146 connected=false;
2148 throw new SocketException (error);
2151 connected=true;
2153 return ret;
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)
2168 socket.SetSocketOption_internal(level, name, obj_val, byte_val, int_val, out error);
2170 #endif
2172 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
2174 EnsureStillUsable();
2176 int error;
2178 SetSocketOption_internal(socket, level, name, null,
2179 opt_value, 0, out error);
2181 if (error != 0) {
2182 throw new SocketException (error);
2186 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
2188 EnsureStillUsable();
2190 int error;
2192 SetSocketOption_internal(socket, level, name, null,
2193 null, opt_value, out error);
2195 if (error != 0) {
2196 throw new SocketException (error);
2200 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
2203 EnsureStillUsable();
2205 if(opt_value==null) {
2206 throw new ArgumentNullException();
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
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;
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);
2230 if (error != 0)
2231 throw new SocketException (error);
2234 #if NET_2_0
2235 public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue) {
2236 EnsureStillUsable();
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);
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)
2251 socket.Shutdown_internal(how, out error);
2253 #endif
2255 public void Shutdown(SocketShutdown how)
2257 EnsureStillUsable();
2259 int error;
2261 Shutdown_internal(socket, how, out error);
2263 if (error != 0) {
2264 throw new SocketException (error);
2268 #if !TARGET_JVM
2269 public override int GetHashCode ()
2271 return (int) socket;
2273 #else
2274 public override int GetHashCode ()
2276 if (socket == null)
2277 return -1;
2279 return socket.GetHashCode();
2281 #endif
2283 #if !TARGET_JVM
2284 protected virtual void Dispose (bool explicitDisposing)
2286 if (disposed)
2287 return;
2289 disposed = true;
2290 connected = false;
2291 if ((int) socket != -1)
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)
2300 blocking_thread.Abort ();
2301 blocking_thread = null;
2304 if (error != 0)
2305 throw new SocketException (error);
2308 #else
2309 private void EnsureStillUsable()
2311 if (disposed && closed)
2312 throw new ObjectDisposedException(this.GetType().ToString());
2314 protected virtual void Dispose (bool explicitDisposing)
2316 if (disposed)
2317 return;
2319 disposed = true;
2320 connected = false;
2321 if (socket != null)
2323 int error;
2324 closed = true;
2325 GHSocket x = socket;
2326 socket = null;
2327 Close_internal (x, out error);
2329 if (error != 0)
2330 throw new SocketException (error);
2333 #endif
2335 #region .Net 2.0 properties and methods
2336 #if NET_2_0
2338 #region Properties
2339 [MonoTODO]
2340 public int ReceiveBufferSize
2342 get { throw new NotImplementedException(); }
2343 set { throw new NotImplementedException(); }
2346 [MonoTODO]
2347 public int SendBufferSize
2349 get { throw new NotImplementedException(); }
2350 set { throw new NotImplementedException(); }
2353 [MonoTODO]
2354 public bool UseOnlyOverlappedIO
2356 get { throw new NotImplementedException(); }
2357 set { throw new NotImplementedException(); }
2360 [MonoTODO]
2361 public bool NoDelay
2363 get { throw new NotImplementedException(); }
2364 set { throw new NotImplementedException(); }
2367 [MonoTODO]
2368 public bool IsBound
2370 get { throw new NotImplementedException(); }
2373 [MonoTODO]
2374 public bool ExclusiveAddressUse
2376 get { throw new NotImplementedException(); }
2377 set { throw new NotImplementedException(); }
2380 [MonoTODO("udp sockets are not supported")]
2381 public bool DontFragment
2383 get { throw new NotImplementedException(); }
2384 set { throw new NotImplementedException(); }
2387 [MonoTODO]
2388 public bool EnableBroadcast
2390 get { throw new NotImplementedException(); }
2391 set { throw new NotImplementedException(); }
2394 [MonoTODO]
2395 public bool MulticastLoopback
2397 get { throw new NotImplementedException(); }
2398 set { throw new NotImplementedException(); }
2401 [MonoTODO]
2402 public short Ttl
2404 get { throw new NotImplementedException(); }
2405 set { throw new NotImplementedException(); }
2408 [MonoTODO]
2409 public int ReceiveTimeout
2411 get { throw new NotImplementedException(); }
2412 set { throw new NotImplementedException(); }
2415 [MonoTODO]
2416 public int SendTimeout
2418 get { throw new NotImplementedException(); }
2419 set { throw new NotImplementedException(); }
2422 #endregion //Properties
2424 #region Methods
2426 [MonoTODO]
2427 public IAsyncResult BeginConnect(IPAddress address, int port,
2428 AsyncCallback requestCallback,
2429 object state)
2431 throw new NotImplementedException();
2434 [MonoTODO]
2435 public IAsyncResult BeginConnect(IPAddress[] addresses, int port,
2436 AsyncCallback requestCallback,
2437 object state)
2439 throw new NotImplementedException();
2442 [MonoTODO]
2443 public IAsyncResult BeginConnect(string host, int port,
2444 AsyncCallback requestCallback,
2445 object state)
2447 throw new NotImplementedException();
2450 [MonoTODO]
2451 public IAsyncResult BeginAccept(int receiveSize, AsyncCallback callback, object state)
2453 throw new NotImplementedException();
2456 [MonoTODO]
2457 public IAsyncResult BeginAccept( Socket acceptSocket,int receiveSize,
2458 AsyncCallback callback, object state)
2460 throw new NotImplementedException();
2463 [MonoNotSupported ("")]
2464 public Socket EndAccept (out byte [] buffer, IAsyncResult asyncResult)
2466 throw new NotImplementedException ();
2469 [MonoNotSupported ("")]
2470 public Socket EndAccept (out byte [] buffer, out int bytesTransferred, IAsyncResult asyncResult)
2472 throw new NotImplementedException ();
2475 [MonoTODO]
2476 public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state)
2478 throw new NotImplementedException();
2481 [MonoNotSupported ("")]
2482 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, object state)
2484 throw new NotImplementedException ();
2487 [MonoNotSupported ("")]
2488 [CLSCompliantAttribute (false)]
2489 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags,
2490 out SocketError errorCode, AsyncCallback callback,
2491 object state)
2493 throw new NotImplementedException ();
2496 [MonoTODO]
2497 public IAsyncResult BeginSend(byte[] buffer, int offset, int size,
2498 SocketFlags socketFlags, out SocketError errorCode,
2499 AsyncCallback callback, object state)
2501 throw new NotImplementedException();
2504 [MonoNotSupported ("")]
2505 public int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
2507 throw new NotImplementedException ();
2510 [MonoNotSupported ("")]
2511 public IAsyncResult BeginReceive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2513 throw new NotImplementedException ();
2516 [CLSCompliantAttribute (false)]
2517 [MonoNotSupported ("")]
2518 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, AsyncCallback callback, Object state)
2520 throw new NotImplementedException ();
2523 [CLSCompliantAttribute (false)]
2524 [MonoNotSupported ("")]
2525 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, Object state)
2527 throw new NotImplementedException ();
2530 [MonoNotSupported ("")]
2531 public int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
2533 throw new NotImplementedException ();
2536 [MonoNotSupported ("")]
2537 public void SendFile (string fileName)
2539 throw new NotImplementedException ();
2542 [MonoNotSupported ("")]
2543 public void SendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags)
2545 throw new NotImplementedException ();
2548 [MonoNotSupported ("")]
2549 public IAsyncResult BeginSendFile (string fileName, AsyncCallback callback, object state)
2551 throw new NotImplementedException ();
2554 [MonoNotSupported ("")]
2555 public IAsyncResult BeginSendFile (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags, AsyncCallback callback, object state)
2557 throw new NotImplementedException ();
2560 [MonoNotSupported ("")]
2561 public void EndSendFile (IAsyncResult asyncResult)
2563 throw new NotImplementedException ();
2566 [MonoTODO]
2567 public void Close(int timeout)
2569 throw new NotImplementedException();
2572 [MonoTODO]
2573 public void Connect(IPAddress address, int port)
2575 throw new NotImplementedException();
2578 [MonoTODO]
2579 public void Connect(IPAddress[] address, int port)
2581 throw new NotImplementedException();
2584 [MonoTODO]
2585 public void Connect(string host, int port)
2587 throw new NotImplementedException();
2590 [MonoNotSupported ("")]
2591 public void Disconnect (bool reuseSocket)
2593 throw new NotImplementedException ();
2596 [MonoNotSupported ("")]
2597 public SocketInformation DuplicateAndClose (int targetProcessId)
2599 throw new NotImplementedException ();
2601 #endregion //Methods
2603 #endif
2604 #endregion
2606 void IDisposable.Dispose ()
2608 Dispose (true);
2609 GC.SuppressFinalize (this);
2612 ~Socket () {
2613 Dispose(false);