1 // System.Net.Sockets.Socket.cs
4 // Phillip Pearson (pp@myelin.co.nz)
5 // Dick Porter <dick@ximian.com>
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Sridhar Kulkarni (sridharkulkarni@gmail.com)
8 // Brian Nickel (brian.nickel@gmail.com)
10 // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
11 // http://www.myelin.co.nz
12 // (c) 2004-2011 Novell, Inc. (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.Collections.Generic;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Threading;
42 using System.Reflection;
44 using System.Net.Configuration;
47 using System.Net.NetworkInformation;
49 namespace System.Net.Sockets
51 public partial class Socket : IDisposable
53 private bool islistening;
54 private bool useoverlappedIO;
55 private const int SOCKET_CLOSED = 10004;
57 private static readonly string timeout_exc_msg = "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond";
59 static void AddSockets (List<Socket> sockets, IList list, string name)
62 foreach (Socket sock in list) {
63 if (sock == null) // MS throws a NullRef
64 throw new ArgumentNullException ("name", "Contains a null element");
71 [MethodImplAttribute(MethodImplOptions.InternalCall)]
72 private extern static void Select_internal (ref Socket [] sockets,
75 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
77 var list = new List<Socket> ();
78 AddSockets (list, checkRead, "checkRead");
79 AddSockets (list, checkWrite, "checkWrite");
80 AddSockets (list, checkError, "checkError");
82 if (list.Count == 3) {
83 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
84 "All the lists are null or empty.");
89 * The 'sockets' array contains: READ socket 0-n, null,
90 * WRITE socket 0-n, null,
91 * ERROR socket 0-n, null
93 Socket [] sockets = list.ToArray ();
94 Select_internal (ref sockets, microSeconds, out error);
97 throw new SocketException (error);
99 if (sockets == null) {
100 if (checkRead != null)
102 if (checkWrite != null)
104 if (checkError != null)
110 int count = sockets.Length;
111 IList currentList = checkRead;
113 for (int i = 0; i < count; i++) {
114 Socket sock = sockets [i];
115 if (sock == null) { // separator
116 if (currentList != null) {
117 // Remove non-signaled sockets after the current one
118 int to_remove = currentList.Count - currentIdx;
119 for (int k = 0; k < to_remove; k++)
120 currentList.RemoveAt (currentIdx);
122 currentList = (mode == 0) ? checkWrite : checkError;
128 if (mode == 1 && currentList == checkWrite && !sock.connected) {
129 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
130 sock.connected = true;
133 // Remove non-signaled sockets before the current one
134 //int max = currentList.Count;
135 while (((Socket) currentList [currentIdx]) != sock) {
136 currentList.RemoveAt (currentIdx);
142 // private constructor used by Accept, which already
143 // has a socket handle to use
144 internal Socket(AddressFamily family, SocketType type,
145 ProtocolType proto, SafeSocketHandle sock)
147 address_family=family;
155 private void SocketDefaults ()
158 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
159 address_family == AddressFamily.InterNetworkV6 */) {
160 /* This is the default, but it
161 * probably has nasty side
162 * effects on Linux, as the
163 * socket option is kludged by
164 * turning on or off PMTU
167 this.DontFragment = false;
171 // Microsoft sets these to 8192, but we are going to keep them
172 // both to the OS defaults as these have a big performance impact.
173 // on WebClient performance.
175 //this.ReceiveBufferSize = 8192;
176 //this.SendBufferSize = 8192;
177 } catch (SocketException) {
182 public Socket (SocketInformation socketInformation)
184 var options = socketInformation.Options;
185 islistening = (options & SocketInformationOptions.Listening) != 0;
186 connected = (options & SocketInformationOptions.Connected) != 0;
187 blocking = (options & SocketInformationOptions.NonBlocking) == 0;
188 useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
190 var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
192 address_family = (AddressFamily) (int) result [0];
193 socket_type = (SocketType) (int) result [1];
194 protocol_type = (ProtocolType) (int) result [2];
195 isbound = (ProtocolType) (int) result [3] != 0;
196 socket = new SafeSocketHandle ((IntPtr) (long) result [4], true);
201 // Returns the amount of data waiting to be read on socket
202 [MethodImplAttribute(MethodImplOptions.InternalCall)]
203 private extern static int Available_internal(IntPtr socket, out int error);
205 private static int Available_internal (SafeSocketHandle safeHandle, out int error)
207 bool release = false;
209 safeHandle.DangerousAddRef (ref release);
210 return Available_internal (safeHandle.DangerousGetHandle (), out error);
213 safeHandle.DangerousRelease ();
217 public int Available {
219 if (disposed && closed)
220 throw new ObjectDisposedException (GetType ().ToString ());
224 ret = Available_internal(socket, out error);
227 throw new SocketException (error);
234 public bool DontFragment {
236 if (disposed && closed) {
237 throw new ObjectDisposedException (GetType ().ToString ());
242 if (address_family == AddressFamily.InterNetwork) {
243 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
244 } else if (address_family == AddressFamily.InterNetworkV6) {
245 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
247 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
250 return(dontfragment);
253 if (disposed && closed) {
254 throw new ObjectDisposedException (GetType ().ToString ());
257 if (address_family == AddressFamily.InterNetwork) {
258 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
259 } else if (address_family == AddressFamily.InterNetworkV6) {
260 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
262 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
267 public bool EnableBroadcast {
269 if (disposed && closed) {
270 throw new ObjectDisposedException (GetType ().ToString ());
273 if (protocol_type != ProtocolType.Udp) {
274 throw new SocketException ((int)SocketError.ProtocolOption);
277 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
280 if (disposed && closed) {
281 throw new ObjectDisposedException (GetType ().ToString ());
284 if (protocol_type != ProtocolType.Udp) {
285 throw new SocketException ((int)SocketError.ProtocolOption);
288 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
292 public bool ExclusiveAddressUse {
294 if (disposed && closed) {
295 throw new ObjectDisposedException (GetType ().ToString ());
298 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
301 if (disposed && closed) {
302 throw new ObjectDisposedException (GetType ().ToString ());
305 throw new InvalidOperationException ("Bind has already been called for this socket");
308 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
312 public bool IsBound {
318 public LingerOption LingerState {
320 if (disposed && closed) {
321 throw new ObjectDisposedException (GetType ().ToString ());
324 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
327 if (disposed && closed) {
328 throw new ObjectDisposedException (GetType ().ToString ());
331 SetSocketOption (SocketOptionLevel.Socket,
332 SocketOptionName.Linger,
337 public bool MulticastLoopback {
339 if (disposed && closed) {
340 throw new ObjectDisposedException (GetType ().ToString ());
343 /* Even though this option can be set
344 * for TCP sockets on Linux, throw
345 * this exception anyway to be
346 * compatible (the MSDN docs say
347 * "Setting this property on a
348 * Transmission Control Protocol (TCP)
349 * socket will have no effect." but
350 * the MS runtime throws the
353 if (protocol_type == ProtocolType.Tcp) {
354 throw new SocketException ((int)SocketError.ProtocolOption);
357 bool multicastloopback;
359 if (address_family == AddressFamily.InterNetwork) {
360 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
361 } else if (address_family == AddressFamily.InterNetworkV6) {
362 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
364 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
367 return(multicastloopback);
370 if (disposed && closed) {
371 throw new ObjectDisposedException (GetType ().ToString ());
374 /* Even though this option can be set
375 * for TCP sockets on Linux, throw
376 * this exception anyway to be
377 * compatible (the MSDN docs say
378 * "Setting this property on a
379 * Transmission Control Protocol (TCP)
380 * socket will have no effect." but
381 * the MS runtime throws the
384 if (protocol_type == ProtocolType.Tcp) {
385 throw new SocketException ((int)SocketError.ProtocolOption);
388 if (address_family == AddressFamily.InterNetwork) {
389 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
390 } else if (address_family == AddressFamily.InterNetworkV6) {
391 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
393 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
399 [MonoTODO ("This doesn't do anything on Mono yet")]
400 public bool UseOnlyOverlappedIO {
402 return(useoverlappedIO);
405 useoverlappedIO = value;
409 public IntPtr Handle {
411 return(socket.DangerousGetHandle ());
415 // Returns the local endpoint details in addr and port
416 [MethodImplAttribute(MethodImplOptions.InternalCall)]
417 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
419 private static SocketAddress LocalEndPoint_internal(SafeSocketHandle safeHandle, int family, out int error)
421 bool release = false;
423 safeHandle.DangerousAddRef (ref release);
424 return LocalEndPoint_internal (safeHandle.DangerousGetHandle (), family, out error);
427 safeHandle.DangerousRelease ();
431 // Wish: support non-IP endpoints.
432 public EndPoint LocalEndPoint {
434 if (disposed && closed)
435 throw new ObjectDisposedException (GetType ().ToString ());
438 * If the seed EndPoint is null, Connect, Bind,
439 * etc has not yet been called. MS returns null
442 if (seed_endpoint == null)
448 sa=LocalEndPoint_internal(socket, (int) address_family, out error);
451 throw new SocketException (error);
453 return seed_endpoint.Create (sa);
457 public SocketType SocketType {
463 public int SendTimeout {
465 if (disposed && closed)
466 throw new ObjectDisposedException (GetType ().ToString ());
468 return (int)GetSocketOption(
469 SocketOptionLevel.Socket,
470 SocketOptionName.SendTimeout);
473 if (disposed && closed)
474 throw new ObjectDisposedException (GetType ().ToString ());
477 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
479 /* According to the MSDN docs we
480 * should adjust values between 1 and
481 * 499 to 500, but the MS runtime
488 SocketOptionLevel.Socket,
489 SocketOptionName.SendTimeout, value);
493 public int ReceiveTimeout {
495 if (disposed && closed)
496 throw new ObjectDisposedException (GetType ().ToString ());
498 return (int)GetSocketOption(
499 SocketOptionLevel.Socket,
500 SocketOptionName.ReceiveTimeout);
503 if (disposed && closed)
504 throw new ObjectDisposedException (GetType ().ToString ());
507 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
514 SocketOptionLevel.Socket,
515 SocketOptionName.ReceiveTimeout, value);
519 public bool AcceptAsync (SocketAsyncEventArgs e)
521 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
523 if (disposed && closed)
524 throw new ObjectDisposedException (GetType ().ToString ());
526 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
528 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
529 if (e.BufferList != null)
530 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
532 throw new ArgumentOutOfRangeException ("e.Count");
534 Socket acceptSocket = e.AcceptSocket;
535 if (acceptSocket != null) {
536 if (acceptSocket.IsBound || acceptSocket.Connected)
537 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
542 w.Init (this, e, SocketOperation.Accept);
545 readQ.Enqueue (e.Worker);
549 socket_pool_queue (Worker.Dispatcher, w.result);
552 // Creates a new system socket, returning the handle
553 [MethodImplAttribute(MethodImplOptions.InternalCall)]
554 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
556 private static SafeSocketHandle Accept_internal(SafeSocketHandle safeHandle, out int error, bool blocking)
559 safeHandle.RegisterForBlockingSyscall ();
560 var ret = Accept_internal (safeHandle.DangerousGetHandle (), out error, blocking);
561 return new SafeSocketHandle (ret, true);
563 safeHandle.UnRegisterForBlockingSyscall ();
567 public Socket Accept() {
568 if (disposed && closed)
569 throw new ObjectDisposedException (GetType ().ToString ());
572 var sock = Accept_internal(socket, out error, blocking);
576 error = SOCKET_CLOSED;
577 throw new SocketException(error);
580 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
581 this.ProtocolType, sock);
583 accepted.seed_endpoint = this.seed_endpoint;
584 accepted.Blocking = this.Blocking;
588 internal void Accept (Socket acceptSocket)
590 if (disposed && closed)
591 throw new ObjectDisposedException (GetType ().ToString ());
594 var sock = Accept_internal (socket, out error, blocking);
598 error = SOCKET_CLOSED;
599 throw new SocketException (error);
602 acceptSocket.address_family = this.AddressFamily;
603 acceptSocket.socket_type = this.SocketType;
604 acceptSocket.protocol_type = this.ProtocolType;
605 acceptSocket.socket = sock;
606 acceptSocket.connected = true;
607 acceptSocket.seed_endpoint = this.seed_endpoint;
608 acceptSocket.Blocking = this.Blocking;
610 /* FIXME: figure out what if anything else
615 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
617 if (disposed && closed)
618 throw new ObjectDisposedException (GetType ().ToString ());
620 if (!isbound || !islistening)
621 throw new InvalidOperationException ();
623 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
626 readQ.Enqueue (req.Worker);
630 socket_pool_queue (Worker.Dispatcher, req);
634 public IAsyncResult BeginAccept (int receiveSize,
635 AsyncCallback callback,
638 if (disposed && closed)
639 throw new ObjectDisposedException (GetType ().ToString ());
642 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
644 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
645 req.Buffer = new byte[receiveSize];
647 req.Size = receiveSize;
648 req.SockFlags = SocketFlags.None;
651 readQ.Enqueue (req.Worker);
655 socket_pool_queue (Worker.Dispatcher, req);
659 public IAsyncResult BeginAccept (Socket acceptSocket,
661 AsyncCallback callback,
664 if (disposed && closed)
665 throw new ObjectDisposedException (GetType ().ToString ());
668 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
670 if (acceptSocket != null) {
671 if (acceptSocket.disposed && acceptSocket.closed)
672 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
674 if (acceptSocket.IsBound)
675 throw new InvalidOperationException ();
677 /* For some reason the MS runtime
678 * barfs if the new socket is not TCP,
679 * even though it's just about to blow
680 * away all those parameters
682 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
683 throw new SocketException ((int)SocketError.InvalidArgument);
686 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
687 req.Buffer = new byte[receiveSize];
689 req.Size = receiveSize;
690 req.SockFlags = SocketFlags.None;
691 req.AcceptSocket = acceptSocket;
694 readQ.Enqueue (req.Worker);
698 socket_pool_queue (Worker.Dispatcher, req);
702 public IAsyncResult BeginConnect (IPAddress address, int port,
703 AsyncCallback callback,
706 if (disposed && closed)
707 throw new ObjectDisposedException (GetType ().ToString ());
710 throw new ArgumentNullException ("address");
712 if (address.ToString ().Length == 0)
713 throw new ArgumentException ("The length of the IP address is zero");
715 if (port <= 0 || port > 65535)
716 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
719 throw new InvalidOperationException ();
721 IPEndPoint iep = new IPEndPoint (address, port);
722 return(BeginConnect (iep, callback, state));
725 public IAsyncResult BeginConnect (string host, int port,
726 AsyncCallback callback,
729 if (disposed && closed)
730 throw new ObjectDisposedException (GetType ().ToString ());
733 throw new ArgumentNullException ("host");
735 if (address_family != AddressFamily.InterNetwork &&
736 address_family != AddressFamily.InterNetworkV6)
737 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
739 if (port <= 0 || port > 65535)
740 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
743 throw new InvalidOperationException ();
745 return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
748 public IAsyncResult BeginDisconnect (bool reuseSocket,
749 AsyncCallback callback,
752 if (disposed && closed)
753 throw new ObjectDisposedException (GetType ().ToString ());
755 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
756 req.ReuseSocket = reuseSocket;
757 socket_pool_queue (Worker.Dispatcher, req);
761 void CheckRange (byte[] buffer, int offset, int size)
764 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
766 if (offset > buffer.Length)
767 throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
770 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
772 if (size > buffer.Length - offset)
773 throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
776 public IAsyncResult BeginReceive(byte[] buffer, int offset,
778 SocketFlags socket_flags,
779 AsyncCallback callback,
782 if (disposed && closed)
783 throw new ObjectDisposedException (GetType ().ToString ());
786 throw new ArgumentNullException ("buffer");
788 CheckRange (buffer, offset, size);
790 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
794 req.SockFlags = socket_flags;
797 readQ.Enqueue (req.Worker);
801 socket_pool_queue (Worker.Dispatcher, req);
805 public IAsyncResult BeginReceive (byte[] buffer, int offset,
806 int size, SocketFlags flags,
807 out SocketError error,
808 AsyncCallback callback,
811 /* As far as I can tell from the docs and from
812 * experimentation, a pointer to the
813 * SocketError parameter is not supposed to be
814 * saved for the async parts. And as we don't
815 * set any socket errors in the setup code, we
816 * just have to set it to Success.
818 error = SocketError.Success;
819 return (BeginReceive (buffer, offset, size, flags, callback, state));
822 [CLSCompliant (false)]
823 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
824 SocketFlags socketFlags,
825 AsyncCallback callback,
828 if (disposed && closed)
829 throw new ObjectDisposedException (GetType ().ToString ());
832 throw new ArgumentNullException ("buffers");
834 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
835 req.Buffers = buffers;
836 req.SockFlags = socketFlags;
839 readQ.Enqueue (req.Worker);
843 socket_pool_queue (Worker.Dispatcher, req);
847 [CLSCompliant (false)]
848 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
849 SocketFlags socketFlags,
850 out SocketError errorCode,
851 AsyncCallback callback,
854 /* I assume the same SocketError semantics as
857 errorCode = SocketError.Success;
858 return (BeginReceive (buffers, socketFlags, callback, state));
861 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
863 SocketFlags socket_flags,
864 ref EndPoint remote_end,
865 AsyncCallback callback,
867 if (disposed && closed)
868 throw new ObjectDisposedException (GetType ().ToString ());
871 throw new ArgumentNullException ("buffer");
873 if (remote_end == null)
874 throw new ArgumentNullException ("remote_end");
876 CheckRange (buffer, offset, size);
878 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
882 req.SockFlags = socket_flags;
883 req.EndPoint = remote_end;
886 readQ.Enqueue (req.Worker);
890 socket_pool_queue (Worker.Dispatcher, req);
895 public IAsyncResult BeginReceiveMessageFrom (
896 byte[] buffer, int offset, int size,
897 SocketFlags socketFlags, ref EndPoint remoteEP,
898 AsyncCallback callback, object state)
900 if (disposed && closed)
901 throw new ObjectDisposedException (GetType ().ToString ());
904 throw new ArgumentNullException ("buffer");
906 if (remoteEP == null)
907 throw new ArgumentNullException ("remoteEP");
909 CheckRange (buffer, offset, size);
911 throw new NotImplementedException ();
914 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
915 AsyncCallback callback, object state)
917 if (disposed && closed)
918 throw new ObjectDisposedException (GetType ().ToString ());
921 throw new ArgumentNullException ("buffer");
923 CheckRange (buffer, offset, size);
926 throw new SocketException ((int)SocketError.NotConnected);
928 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
932 req.SockFlags = socket_flags;
935 writeQ.Enqueue (req.Worker);
936 count = writeQ.Count;
939 socket_pool_queue (Worker.Dispatcher, req);
943 public IAsyncResult BeginSend (byte[] buffer, int offset,
945 SocketFlags socketFlags,
946 out SocketError errorCode,
947 AsyncCallback callback,
951 errorCode = SocketError.NotConnected;
952 throw new SocketException ((int)errorCode);
955 errorCode = SocketError.Success;
957 return (BeginSend (buffer, offset, size, socketFlags, callback,
961 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
962 SocketFlags socketFlags,
963 AsyncCallback callback,
966 if (disposed && closed)
967 throw new ObjectDisposedException (GetType ().ToString ());
970 throw new ArgumentNullException ("buffers");
973 throw new SocketException ((int)SocketError.NotConnected);
975 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
976 req.Buffers = buffers;
977 req.SockFlags = socketFlags;
980 writeQ.Enqueue (req.Worker);
981 count = writeQ.Count;
984 socket_pool_queue (Worker.Dispatcher, req);
988 [CLSCompliant (false)]
989 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
990 SocketFlags socketFlags,
991 out SocketError errorCode,
992 AsyncCallback callback,
996 errorCode = SocketError.NotConnected;
997 throw new SocketException ((int)errorCode);
1000 errorCode = SocketError.Success;
1001 return (BeginSend (buffers, socketFlags, callback, state));
1004 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
1006 sealed class SendFileAsyncResult : IAsyncResult {
1010 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
1016 public object AsyncState {
1017 get { return ares.AsyncState; }
1020 public WaitHandle AsyncWaitHandle {
1021 get { return ares.AsyncWaitHandle; }
1024 public bool CompletedSynchronously {
1025 get { return ares.CompletedSynchronously; }
1028 public bool IsCompleted {
1029 get { return ares.IsCompleted; }
1032 public SendFileHandler Delegate {
1036 public IAsyncResult Original {
1037 get { return ares; }
1041 public IAsyncResult BeginSendFile (string fileName,
1042 AsyncCallback callback,
1045 if (disposed && closed)
1046 throw new ObjectDisposedException (GetType ().ToString ());
1049 throw new NotSupportedException ();
1051 if (!File.Exists (fileName))
1052 throw new FileNotFoundException ();
1054 return BeginSendFile (fileName, null, null, 0, callback, state);
1057 public IAsyncResult BeginSendFile (string fileName,
1060 TransmitFileOptions flags,
1061 AsyncCallback callback,
1064 if (disposed && closed)
1065 throw new ObjectDisposedException (GetType ().ToString ());
1068 throw new NotSupportedException ();
1070 if (!File.Exists (fileName))
1071 throw new FileNotFoundException ();
1073 SendFileHandler d = new SendFileHandler (SendFile);
1074 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, ar => {
1075 SendFileAsyncResult sfar = new SendFileAsyncResult (d, ar);
1080 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1082 SocketFlags socket_flags,
1083 EndPoint remote_end,
1084 AsyncCallback callback,
1086 if (disposed && closed)
1087 throw new ObjectDisposedException (GetType ().ToString ());
1090 throw new ArgumentNullException ("buffer");
1092 CheckRange (buffer, offset, size);
1094 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1095 req.Buffer = buffer;
1096 req.Offset = offset;
1098 req.SockFlags = socket_flags;
1099 req.EndPoint = remote_end;
1102 writeQ.Enqueue (req.Worker);
1103 count = writeQ.Count;
1106 socket_pool_queue (Worker.Dispatcher, req);
1110 // Creates a new system socket, returning the handle
1111 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1112 private extern static void Bind_internal(IntPtr sock,
1116 private static void Bind_internal (SafeSocketHandle safeHandle,
1120 bool release = false;
1122 safeHandle.DangerousAddRef (ref release);
1123 Bind_internal (safeHandle.DangerousGetHandle (), sa, out error);
1126 safeHandle.DangerousRelease ();
1130 public void Bind(EndPoint local_end) {
1131 if (disposed && closed)
1132 throw new ObjectDisposedException (GetType ().ToString ());
1134 if (local_end == null)
1135 throw new ArgumentNullException("local_end");
1139 Bind_internal(socket, local_end.Serialize(), out error);
1141 throw new SocketException (error);
1145 seed_endpoint = local_end;
1148 public void Connect (IPAddress address, int port)
1150 Connect (new IPEndPoint (address, port));
1153 public void Connect (IPAddress[] addresses, int port)
1155 if (disposed && closed)
1156 throw new ObjectDisposedException (GetType ().ToString ());
1158 if (addresses == null)
1159 throw new ArgumentNullException ("addresses");
1161 if (this.AddressFamily != AddressFamily.InterNetwork &&
1162 this.AddressFamily != AddressFamily.InterNetworkV6)
1163 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1166 throw new InvalidOperationException ();
1168 /* FIXME: do non-blocking sockets Poll here? */
1170 foreach (IPAddress address in addresses) {
1171 IPEndPoint iep = new IPEndPoint (address, port);
1172 SocketAddress serial = iep.Serialize ();
1174 Connect_internal (socket, serial, out error);
1178 seed_endpoint = iep;
1180 } else if (error != (int)SocketError.InProgress &&
1181 error != (int)SocketError.WouldBlock) {
1186 Poll (-1, SelectMode.SelectWrite);
1187 error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1191 seed_endpoint = iep;
1197 throw new SocketException (error);
1200 public void Connect (string host, int port)
1202 IPAddress [] addresses = Dns.GetHostAddresses (host);
1203 Connect (addresses, port);
1206 public bool DisconnectAsync (SocketAsyncEventArgs e)
1208 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1209 if (disposed && closed)
1210 throw new ObjectDisposedException (GetType ().ToString ());
1213 e.Worker.Init (this, e, SocketOperation.Disconnect);
1214 socket_pool_queue (Worker.Dispatcher, e.Worker.result);
1218 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1219 extern static void Disconnect_internal(IntPtr sock, bool reuse, out int error);
1221 private static void Disconnect_internal(SafeSocketHandle safeHandle, bool reuse, out int error)
1223 bool release = false;
1225 safeHandle.DangerousAddRef (ref release);
1226 Disconnect_internal (safeHandle.DangerousGetHandle (), reuse, out error);
1229 safeHandle.DangerousRelease ();
1233 /* According to the docs, the MS runtime will throw
1234 * PlatformNotSupportedException if the platform is
1235 * newer than w2k. We should be able to cope...
1237 public void Disconnect (bool reuseSocket)
1239 if (disposed && closed)
1240 throw new ObjectDisposedException (GetType ().ToString ());
1244 Disconnect_internal (socket, reuseSocket, out error);
1248 /* ERROR_NOT_SUPPORTED */
1249 throw new PlatformNotSupportedException ();
1251 throw new SocketException (error);
1258 /* Do managed housekeeping here... */
1263 [MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
1264 public SocketInformation DuplicateAndClose (int targetProcessId)
1266 var si = new SocketInformation ();
1268 (islistening ? SocketInformationOptions.Listening : 0) |
1269 (connected ? SocketInformationOptions.Connected : 0) |
1270 (blocking ? 0 : SocketInformationOptions.NonBlocking) |
1271 (useoverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
1273 si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)Handle);
1280 public Socket EndAccept (IAsyncResult result)
1285 return(EndAccept (out buffer, out bytes, result));
1288 public Socket EndAccept (out byte[] buffer, IAsyncResult asyncResult)
1291 return(EndAccept (out buffer, out bytes, asyncResult));
1294 public Socket EndAccept (out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
1296 if (disposed && closed)
1297 throw new ObjectDisposedException (GetType ().ToString ());
1299 if (asyncResult == null)
1300 throw new ArgumentNullException ("asyncResult");
1302 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1304 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1306 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1307 throw InvalidAsyncOp ("EndAccept");
1308 if (!asyncResult.IsCompleted)
1309 asyncResult.AsyncWaitHandle.WaitOne ();
1311 req.CheckIfThrowDelayedException ();
1313 buffer = req.Buffer;
1314 bytesTransferred = req.Total;
1319 public void EndConnect (IAsyncResult result)
1321 if (disposed && closed)
1322 throw new ObjectDisposedException (GetType ().ToString ());
1325 throw new ArgumentNullException ("result");
1327 SocketAsyncResult req = result as SocketAsyncResult;
1329 throw new ArgumentException ("Invalid IAsyncResult", "result");
1331 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1332 throw InvalidAsyncOp ("EndConnect");
1333 if (!result.IsCompleted)
1334 result.AsyncWaitHandle.WaitOne();
1336 req.CheckIfThrowDelayedException();
1339 public void EndDisconnect (IAsyncResult asyncResult)
1341 if (disposed && closed)
1342 throw new ObjectDisposedException (GetType ().ToString ());
1344 if (asyncResult == null)
1345 throw new ArgumentNullException ("asyncResult");
1347 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1349 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1351 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1352 throw InvalidAsyncOp ("EndDisconnect");
1353 if (!asyncResult.IsCompleted)
1354 asyncResult.AsyncWaitHandle.WaitOne ();
1356 req.CheckIfThrowDelayedException ();
1360 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
1361 ref SocketFlags socketFlags,
1362 ref EndPoint endPoint,
1363 out IPPacketInformation ipPacketInformation)
1365 if (disposed && closed)
1366 throw new ObjectDisposedException (GetType ().ToString ());
1368 if (asyncResult == null)
1369 throw new ArgumentNullException ("asyncResult");
1371 if (endPoint == null)
1372 throw new ArgumentNullException ("endPoint");
1374 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1376 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1378 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1379 throw InvalidAsyncOp ("EndReceiveMessageFrom");
1380 throw new NotImplementedException ();
1383 public void EndSendFile (IAsyncResult asyncResult)
1385 if (disposed && closed)
1386 throw new ObjectDisposedException (GetType ().ToString ());
1388 if (asyncResult == null)
1389 throw new ArgumentNullException ("asyncResult");
1391 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
1393 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1395 ares.Delegate.EndInvoke (ares.Original);
1398 public int EndSendTo (IAsyncResult result)
1400 if (disposed && closed)
1401 throw new ObjectDisposedException (GetType ().ToString ());
1404 throw new ArgumentNullException ("result");
1406 SocketAsyncResult req = result as SocketAsyncResult;
1408 throw new ArgumentException ("Invalid IAsyncResult", "result");
1410 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1411 throw InvalidAsyncOp ("EndSendTo");
1412 if (!result.IsCompleted)
1413 result.AsyncWaitHandle.WaitOne();
1415 req.CheckIfThrowDelayedException();
1419 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1420 private extern static void GetSocketOption_arr_internal(IntPtr socket,
1421 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
1424 private static void GetSocketOption_arr_internal (SafeSocketHandle safeHandle,
1425 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
1428 bool release = false;
1430 safeHandle.DangerousAddRef (ref release);
1431 GetSocketOption_arr_internal (safeHandle.DangerousGetHandle (), level, name, ref byte_val, out error);
1434 safeHandle.DangerousRelease ();
1438 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
1440 if (disposed && closed)
1441 throw new ObjectDisposedException (GetType ().ToString ());
1443 if (optionValue == null)
1444 throw new SocketException ((int) SocketError.Fault,
1445 "Error trying to dereference an invalid pointer");
1449 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
1452 throw new SocketException (error);
1455 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
1457 if (disposed && closed)
1458 throw new ObjectDisposedException (GetType ().ToString ());
1460 byte[] byte_val=new byte[length];
1463 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
1466 throw new SocketException (error);
1471 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1472 // common options between UNIX and Winsock are FIONREAD,
1473 // FIONBIO and SIOCATMARK. Anything else will depend on the
1474 // system except SIO_KEEPALIVE_VALS which is properly handled
1475 // on both windows and linux.
1476 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1477 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
1478 byte [] output, out int error);
1480 private static int WSAIoctl (SafeSocketHandle safeHandle, int ioctl_code, byte [] input,
1481 byte [] output, out int error)
1483 bool release = false;
1485 safeHandle.DangerousAddRef (ref release);
1486 return WSAIoctl (safeHandle.DangerousGetHandle (), ioctl_code, input, output, out error);
1489 safeHandle.DangerousRelease ();
1493 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1496 throw new ObjectDisposedException (GetType ().ToString ());
1499 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
1503 throw new SocketException (error);
1506 throw new InvalidOperationException ("Must use Blocking property instead.");
1511 public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
1513 return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
1516 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1517 private extern static void Listen_internal(IntPtr sock, int backlog, out int error);
1519 private static void Listen_internal (SafeSocketHandle safeHandle, int backlog, out int error)
1521 bool release = false;
1523 safeHandle.DangerousAddRef (ref release);
1524 Listen_internal (safeHandle.DangerousGetHandle (), backlog, out error);
1527 safeHandle.DangerousRelease ();
1531 public void Listen (int backlog)
1533 if (disposed && closed)
1534 throw new ObjectDisposedException (GetType ().ToString ());
1537 throw new SocketException ((int)SocketError.InvalidArgument);
1540 Listen_internal(socket, backlog, out error);
1543 throw new SocketException (error);
1548 public bool Poll (int time_us, SelectMode mode)
1550 if (disposed && closed)
1551 throw new ObjectDisposedException (GetType ().ToString ());
1553 if (mode != SelectMode.SelectRead &&
1554 mode != SelectMode.SelectWrite &&
1555 mode != SelectMode.SelectError)
1556 throw new NotSupportedException ("'mode' parameter is not valid.");
1559 bool result = Poll_internal (socket, mode, time_us, out error);
1561 throw new SocketException (error);
1563 if (mode == SelectMode.SelectWrite && result && !connected) {
1564 /* Update the connected state; for
1565 * non-blocking Connect()s this is
1566 * when we can find out that the
1567 * connect succeeded.
1569 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
1577 public int Receive (byte [] buffer)
1579 return Receive (buffer, SocketFlags.None);
1582 public int Receive (byte [] buffer, SocketFlags flags)
1584 if (disposed && closed)
1585 throw new ObjectDisposedException (GetType ().ToString ());
1588 throw new ArgumentNullException ("buffer");
1592 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
1594 if (error != SocketError.Success) {
1595 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1596 throw new SocketException ((int) error, timeout_exc_msg);
1597 throw new SocketException ((int) error);
1603 public int Receive (byte [] buffer, int size, SocketFlags flags)
1605 if (disposed && closed)
1606 throw new ObjectDisposedException (GetType ().ToString ());
1609 throw new ArgumentNullException ("buffer");
1611 CheckRange (buffer, 0, size);
1615 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
1617 if (error != SocketError.Success) {
1618 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1619 throw new SocketException ((int) error, timeout_exc_msg);
1620 throw new SocketException ((int) error);
1626 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
1628 if (disposed && closed)
1629 throw new ObjectDisposedException (GetType ().ToString ());
1632 throw new ArgumentNullException ("buffer");
1634 CheckRange (buffer, offset, size);
1638 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
1640 if (error != SocketError.Success) {
1641 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1642 throw new SocketException ((int) error, timeout_exc_msg);
1643 throw new SocketException ((int) error);
1649 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
1651 if (disposed && closed)
1652 throw new ObjectDisposedException (GetType ().ToString ());
1655 throw new ArgumentNullException ("buffer");
1657 CheckRange (buffer, offset, size);
1659 return Receive_nochecks (buffer, offset, size, flags, out error);
1662 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
1664 if (disposed && closed)
1665 throw new ObjectDisposedException (GetType ().ToString ());
1667 // We do not support recv into multiple buffers yet
1668 if (e.BufferList != null)
1669 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1670 if (e.RemoteEndPoint == null)
1671 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1674 e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
1675 SocketAsyncResult res = e.Worker.result;
1676 res.Buffer = e.Buffer;
1677 res.Offset = e.Offset;
1679 res.EndPoint = e.RemoteEndPoint;
1680 res.SockFlags = e.SocketFlags;
1683 readQ.Enqueue (e.Worker);
1684 count = readQ.Count;
1687 socket_pool_queue (Worker.Dispatcher, res);
1691 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
1693 if (disposed && closed)
1694 throw new ObjectDisposedException (GetType ().ToString ());
1697 throw new ArgumentNullException ("buffer");
1699 if (remoteEP == null)
1700 throw new ArgumentNullException ("remoteEP");
1702 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
1705 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
1707 if (disposed && closed)
1708 throw new ObjectDisposedException (GetType ().ToString ());
1711 throw new ArgumentNullException ("buffer");
1713 if (remoteEP == null)
1714 throw new ArgumentNullException ("remoteEP");
1716 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
1719 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
1720 ref EndPoint remoteEP)
1722 if (disposed && closed)
1723 throw new ObjectDisposedException (GetType ().ToString ());
1726 throw new ArgumentNullException ("buffer");
1728 if (remoteEP == null)
1729 throw new ArgumentNullException ("remoteEP");
1731 if (size < 0 || size > buffer.Length)
1732 throw new ArgumentOutOfRangeException ("size");
1734 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
1737 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1738 private extern static int RecvFrom_internal(IntPtr sock,
1743 ref SocketAddress sockaddr,
1746 private static int RecvFrom_internal (SafeSocketHandle safeHandle,
1751 ref SocketAddress sockaddr,
1755 safeHandle.RegisterForBlockingSyscall ();
1756 return RecvFrom_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, ref sockaddr, out error);
1758 safeHandle.UnRegisterForBlockingSyscall ();
1762 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
1763 ref EndPoint remoteEP)
1765 if (disposed && closed)
1766 throw new ObjectDisposedException (GetType ().ToString ());
1769 throw new ArgumentNullException ("buffer");
1771 if (remoteEP == null)
1772 throw new ArgumentNullException ("remoteEP");
1774 CheckRange (buffer, offset, size);
1776 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
1779 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1780 ref EndPoint remote_end)
1783 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
1786 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
1787 ref EndPoint remote_end, bool throwOnError, out int error)
1789 SocketAddress sockaddr = remote_end.Serialize();
1790 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1791 SocketError err = (SocketError) error;
1793 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
1795 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
1797 throw new SocketException ((int) SocketError.TimedOut, timeout_exc_msg);
1798 error = (int) SocketError.TimedOut;
1803 throw new SocketException (error);
1810 // If sockaddr is null then we're a connection
1811 // oriented protocol and should ignore the
1812 // remote_end parameter (see MSDN
1813 // documentation for Socket.ReceiveFrom(...) )
1815 if ( sockaddr != null ) {
1816 // Stupidly, EndPoint.Create() is an
1818 remote_end = remote_end.Create (sockaddr);
1821 seed_endpoint = remote_end;
1826 [MonoTODO ("Not implemented")]
1827 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
1829 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1830 if (disposed && closed)
1831 throw new ObjectDisposedException (GetType ().ToString ());
1833 throw new NotImplementedException ();
1836 [MonoTODO ("Not implemented")]
1837 public int ReceiveMessageFrom (byte[] buffer, int offset,
1839 ref SocketFlags socketFlags,
1840 ref EndPoint remoteEP,
1841 out IPPacketInformation ipPacketInformation)
1843 if (disposed && closed)
1844 throw new ObjectDisposedException (GetType ().ToString ());
1847 throw new ArgumentNullException ("buffer");
1849 if (remoteEP == null)
1850 throw new ArgumentNullException ("remoteEP");
1852 CheckRange (buffer, offset, size);
1854 /* FIXME: figure out how we get hold of the
1855 * IPPacketInformation
1857 throw new NotImplementedException ();
1860 [MonoTODO ("Not implemented")]
1861 public bool SendPacketsAsync (SocketAsyncEventArgs e)
1863 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1865 if (disposed && closed)
1866 throw new ObjectDisposedException (GetType ().ToString ());
1868 throw new NotImplementedException ();
1871 public int Send (byte [] buf)
1873 if (disposed && closed)
1874 throw new ObjectDisposedException (GetType ().ToString ());
1877 throw new ArgumentNullException ("buf");
1881 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
1883 if (error != SocketError.Success)
1884 throw new SocketException ((int) error);
1889 public int Send (byte [] buf, SocketFlags flags)
1891 if (disposed && closed)
1892 throw new ObjectDisposedException (GetType ().ToString ());
1895 throw new ArgumentNullException ("buf");
1899 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
1901 if (error != SocketError.Success)
1902 throw new SocketException ((int) error);
1907 public int Send (byte [] buf, int size, SocketFlags flags)
1909 if (disposed && closed)
1910 throw new ObjectDisposedException (GetType ().ToString ());
1913 throw new ArgumentNullException ("buf");
1915 CheckRange (buf, 0, size);
1919 int ret = Send_nochecks (buf, 0, size, flags, out error);
1921 if (error != SocketError.Success)
1922 throw new SocketException ((int) error);
1927 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
1929 if (disposed && closed)
1930 throw new ObjectDisposedException (GetType ().ToString ());
1933 throw new ArgumentNullException ("buffer");
1935 CheckRange (buf, offset, size);
1939 int ret = Send_nochecks (buf, offset, size, flags, out error);
1941 if (error != SocketError.Success)
1942 throw new SocketException ((int) error);
1947 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
1949 if (disposed && closed)
1950 throw new ObjectDisposedException (GetType ().ToString ());
1953 throw new ArgumentNullException ("buffer");
1955 CheckRange (buf, offset, size);
1957 return Send_nochecks (buf, offset, size, flags, out error);
1960 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1961 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
1963 private static bool SendFile (SafeSocketHandle safeHandle, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags)
1966 safeHandle.RegisterForBlockingSyscall ();
1967 return SendFile (safeHandle.DangerousGetHandle (), filename, pre_buffer, post_buffer, flags);
1969 safeHandle.UnRegisterForBlockingSyscall ();
1973 public void SendFile (string fileName)
1975 if (disposed && closed)
1976 throw new ObjectDisposedException (GetType ().ToString ());
1979 throw new NotSupportedException ();
1982 throw new InvalidOperationException ();
1984 SendFile (fileName, null, null, 0);
1987 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
1989 if (disposed && closed)
1990 throw new ObjectDisposedException (GetType ().ToString ());
1993 throw new NotSupportedException ();
1996 throw new InvalidOperationException ();
1998 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
1999 SocketException exc = new SocketException ();
2000 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
2001 throw new FileNotFoundException ();
2006 public bool SendToAsync (SocketAsyncEventArgs e)
2008 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
2010 if (disposed && closed)
2011 throw new ObjectDisposedException (GetType ().ToString ());
2012 if (e.BufferList != null)
2013 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
2014 if (e.RemoteEndPoint == null)
2015 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
2018 e.Worker.Init (this, e, SocketOperation.SendTo);
2019 SocketAsyncResult res = e.Worker.result;
2020 res.Buffer = e.Buffer;
2021 res.Offset = e.Offset;
2023 res.SockFlags = e.SocketFlags;
2024 res.EndPoint = e.RemoteEndPoint;
2027 writeQ.Enqueue (e.Worker);
2028 count = writeQ.Count;
2031 socket_pool_queue (Worker.Dispatcher, res);
2035 public int SendTo (byte [] buffer, EndPoint remote_end)
2037 if (disposed && closed)
2038 throw new ObjectDisposedException (GetType ().ToString ());
2041 throw new ArgumentNullException ("buffer");
2043 if (remote_end == null)
2044 throw new ArgumentNullException ("remote_end");
2046 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
2049 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
2051 if (disposed && closed)
2052 throw new ObjectDisposedException (GetType ().ToString ());
2055 throw new ArgumentNullException ("buffer");
2057 if (remote_end == null)
2058 throw new ArgumentNullException ("remote_end");
2060 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
2063 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
2065 if (disposed && closed)
2066 throw new ObjectDisposedException (GetType ().ToString ());
2069 throw new ArgumentNullException ("buffer");
2071 if (remote_end == null)
2072 throw new ArgumentNullException ("remote_end");
2074 CheckRange (buffer, 0, size);
2076 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
2079 [MethodImplAttribute(MethodImplOptions.InternalCall)]
2080 private extern static int SendTo_internal(IntPtr sock,
2088 private static int SendTo_internal (SafeSocketHandle safeHandle,
2097 safeHandle.RegisterForBlockingSyscall ();
2098 return SendTo_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, sa, out error);
2100 safeHandle.UnRegisterForBlockingSyscall ();
2104 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2105 EndPoint remote_end)
2107 if (disposed && closed)
2108 throw new ObjectDisposedException (GetType ().ToString ());
2111 throw new ArgumentNullException ("buffer");
2113 if (remote_end == null)
2114 throw new ArgumentNullException("remote_end");
2116 CheckRange (buffer, offset, size);
2118 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2121 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2122 EndPoint remote_end)
2124 SocketAddress sockaddr = remote_end.Serialize ();
2128 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2130 SocketError err = (SocketError) error;
2132 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2135 throw new SocketException (error);
2140 seed_endpoint = remote_end;
2145 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2147 if (disposed && closed)
2148 throw new ObjectDisposedException (GetType ().ToString ());
2150 // I'd throw an ArgumentNullException, but this is what MS does.
2151 if (optionValue == null)
2152 throw new SocketException ((int) SocketError.Fault,
2153 "Error trying to dereference an invalid pointer");
2157 SetSocketOption_internal (socket, optionLevel, optionName, null,
2158 optionValue, 0, out error);
2161 if (error == (int) SocketError.InvalidArgument)
2162 throw new ArgumentException ();
2163 throw new SocketException (error);
2167 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
2169 if (disposed && closed)
2170 throw new ObjectDisposedException (GetType ().ToString ());
2172 // NOTE: if a null is passed, the byte[] overload is used instead...
2173 if (optionValue == null)
2174 throw new ArgumentNullException("optionValue");
2178 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
2179 LingerOption linger = optionValue as LingerOption;
2181 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
2182 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
2183 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2184 MulticastOption multicast = optionValue as MulticastOption;
2185 if (multicast == null)
2186 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
2187 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2188 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2189 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
2190 if (multicast == null)
2191 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
2192 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2194 throw new ArgumentException ("Invalid value specified.", "optionValue");
2198 if (error == (int) SocketError.InvalidArgument)
2199 throw new ArgumentException ();
2200 throw new SocketException (error);
2204 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
2206 if (disposed && closed)
2207 throw new ObjectDisposedException (GetType ().ToString ());
2210 int int_val = (optionValue) ? 1 : 0;
2211 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
2213 if (error == (int) SocketError.InvalidArgument)
2214 throw new ArgumentException ();
2215 throw new SocketException (error);