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)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 using System.Collections;
39 using System.Collections.Generic;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
42 using System.Threading;
43 using System.Reflection;
45 using System.Net.Configuration;
49 using System.Net.NetworkInformation;
52 namespace System.Net.Sockets
54 public partial class Socket : IDisposable
56 private bool islistening;
57 private bool useoverlappedIO;
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");
72 [MethodImplAttribute(MethodImplOptions.InternalCall)]
73 private extern static void Select_internal (ref Socket [] sockets,
77 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
79 var list = new List<Socket> ();
80 AddSockets (list, checkRead, "checkRead");
81 AddSockets (list, checkWrite, "checkWrite");
82 AddSockets (list, checkError, "checkError");
84 if (list.Count == 3) {
85 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
86 "All the lists are null or empty.");
91 * The 'sockets' array contains: READ socket 0-n, null,
92 * WRITE socket 0-n, null,
93 * ERROR socket 0-n, null
95 Socket [] sockets = list.ToArray ();
96 Select_internal (ref sockets, microSeconds, out error);
99 throw new SocketException (error);
101 if (sockets == null) {
102 if (checkRead != null)
104 if (checkWrite != null)
106 if (checkError != null)
112 int count = sockets.Length;
113 IList currentList = checkRead;
115 for (int i = 0; i < count; i++) {
116 Socket sock = sockets [i];
117 if (sock == null) { // separator
118 if (currentList != null) {
119 // Remove non-signaled sockets after the current one
120 int to_remove = currentList.Count - currentIdx;
121 for (int k = 0; k < to_remove; k++)
122 currentList.RemoveAt (currentIdx);
124 currentList = (mode == 0) ? checkWrite : checkError;
130 if (mode == 1 && currentList == checkWrite && !sock.connected) {
131 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
132 sock.connected = true;
135 // Remove non-signaled sockets before the current one
136 //int max = currentList.Count;
137 while (((Socket) currentList [currentIdx]) != sock) {
138 currentList.RemoveAt (currentIdx);
144 // private constructor used by Accept, which already
145 // has a socket handle to use
146 internal Socket(AddressFamily family, SocketType type,
147 ProtocolType proto, IntPtr sock)
149 address_family=family;
157 private void SocketDefaults ()
160 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
161 address_family == AddressFamily.InterNetworkV6 */) {
162 /* This is the default, but it
163 * probably has nasty side
164 * effects on Linux, as the
165 * socket option is kludged by
166 * turning on or off PMTU
169 this.DontFragment = false;
173 // Microsoft sets these to 8192, but we are going to keep them
174 // both to the OS defaults as these have a big performance impact.
175 // on WebClient performance.
177 //this.ReceiveBufferSize = 8192;
178 //this.SendBufferSize = 8192;
179 } catch (SocketException) {
184 public Socket (SocketInformation socketInformation)
186 var options = socketInformation.Options;
187 islistening = (options & SocketInformationOptions.Listening) != 0;
188 connected = (options & SocketInformationOptions.Connected) != 0;
189 blocking = (options & SocketInformationOptions.NonBlocking) == 0;
190 useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
192 var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
194 address_family = (AddressFamily) (int) result [0];
195 socket_type = (SocketType) (int) result [1];
196 protocol_type = (ProtocolType) (int) result [2];
197 isbound = (ProtocolType) (int) result [3] != 0;
198 socket = (IntPtr) (long) result [4];
204 // Returns the amount of data waiting to be read on socket
205 [MethodImplAttribute(MethodImplOptions.InternalCall)]
206 private extern static int Available_internal(IntPtr socket, out int error);
209 public int Available {
211 if (disposed && closed)
212 throw new ObjectDisposedException (GetType ().ToString ());
216 ret = Available_internal(socket, out error);
219 throw new SocketException (error);
226 public bool DontFragment {
228 if (disposed && closed) {
229 throw new ObjectDisposedException (GetType ().ToString ());
234 if (address_family == AddressFamily.InterNetwork) {
235 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
236 } else if (address_family == AddressFamily.InterNetworkV6) {
237 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
239 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
242 return(dontfragment);
245 if (disposed && closed) {
246 throw new ObjectDisposedException (GetType ().ToString ());
249 if (address_family == AddressFamily.InterNetwork) {
250 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
251 } else if (address_family == AddressFamily.InterNetworkV6) {
252 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
254 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
259 public bool EnableBroadcast {
261 if (disposed && closed) {
262 throw new ObjectDisposedException (GetType ().ToString ());
265 if (protocol_type != ProtocolType.Udp) {
266 throw new SocketException ((int)SocketError.ProtocolOption);
269 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
272 if (disposed && closed) {
273 throw new ObjectDisposedException (GetType ().ToString ());
276 if (protocol_type != ProtocolType.Udp) {
277 throw new SocketException ((int)SocketError.ProtocolOption);
280 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
284 public bool ExclusiveAddressUse {
286 if (disposed && closed) {
287 throw new ObjectDisposedException (GetType ().ToString ());
290 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
293 if (disposed && closed) {
294 throw new ObjectDisposedException (GetType ().ToString ());
297 throw new InvalidOperationException ("Bind has already been called for this socket");
300 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
304 public bool IsBound {
310 public LingerOption LingerState {
312 if (disposed && closed) {
313 throw new ObjectDisposedException (GetType ().ToString ());
316 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
319 if (disposed && closed) {
320 throw new ObjectDisposedException (GetType ().ToString ());
323 SetSocketOption (SocketOptionLevel.Socket,
324 SocketOptionName.Linger,
329 public bool MulticastLoopback {
331 if (disposed && closed) {
332 throw new ObjectDisposedException (GetType ().ToString ());
335 /* Even though this option can be set
336 * for TCP sockets on Linux, throw
337 * this exception anyway to be
338 * compatible (the MSDN docs say
339 * "Setting this property on a
340 * Transmission Control Protocol (TCP)
341 * socket will have no effect." but
342 * the MS runtime throws the
345 if (protocol_type == ProtocolType.Tcp) {
346 throw new SocketException ((int)SocketError.ProtocolOption);
349 bool multicastloopback;
351 if (address_family == AddressFamily.InterNetwork) {
352 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
353 } else if (address_family == AddressFamily.InterNetworkV6) {
354 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
356 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
359 return(multicastloopback);
362 if (disposed && closed) {
363 throw new ObjectDisposedException (GetType ().ToString ());
366 /* Even though this option can be set
367 * for TCP sockets on Linux, throw
368 * this exception anyway to be
369 * compatible (the MSDN docs say
370 * "Setting this property on a
371 * Transmission Control Protocol (TCP)
372 * socket will have no effect." but
373 * the MS runtime throws the
376 if (protocol_type == ProtocolType.Tcp) {
377 throw new SocketException ((int)SocketError.ProtocolOption);
380 if (address_family == AddressFamily.InterNetwork) {
381 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
382 } else if (address_family == AddressFamily.InterNetworkV6) {
383 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
385 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
391 [MonoTODO ("This doesn't do anything on Mono yet")]
392 public bool UseOnlyOverlappedIO {
394 return(useoverlappedIO);
397 useoverlappedIO = value;
401 public IntPtr Handle {
408 // Returns the local endpoint details in addr and port
409 [MethodImplAttribute(MethodImplOptions.InternalCall)]
410 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
413 // Wish: support non-IP endpoints.
414 public EndPoint LocalEndPoint {
416 if (disposed && closed)
417 throw new ObjectDisposedException (GetType ().ToString ());
420 * If the seed EndPoint is null, Connect, Bind,
421 * etc has not yet been called. MS returns null
424 if (seed_endpoint == null)
430 sa=LocalEndPoint_internal(socket, (int) address_family, out error);
433 throw new SocketException (error);
435 return seed_endpoint.Create (sa);
439 public SocketType SocketType {
445 public int SendTimeout {
447 if (disposed && closed)
448 throw new ObjectDisposedException (GetType ().ToString ());
450 return (int)GetSocketOption(
451 SocketOptionLevel.Socket,
452 SocketOptionName.SendTimeout);
455 if (disposed && closed)
456 throw new ObjectDisposedException (GetType ().ToString ());
459 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
461 /* According to the MSDN docs we
462 * should adjust values between 1 and
463 * 499 to 500, but the MS runtime
470 SocketOptionLevel.Socket,
471 SocketOptionName.SendTimeout, value);
475 public int ReceiveTimeout {
477 if (disposed && closed)
478 throw new ObjectDisposedException (GetType ().ToString ());
480 return (int)GetSocketOption(
481 SocketOptionLevel.Socket,
482 SocketOptionName.ReceiveTimeout);
485 if (disposed && closed)
486 throw new ObjectDisposedException (GetType ().ToString ());
489 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
496 SocketOptionLevel.Socket,
497 SocketOptionName.ReceiveTimeout, value);
502 public bool AcceptAsync (SocketAsyncEventArgs e)
504 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
506 if (disposed && closed)
507 throw new ObjectDisposedException (GetType ().ToString ());
509 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
511 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
512 if (e.BufferList != null)
513 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
515 throw new ArgumentOutOfRangeException ("e.Count");
517 Socket acceptSocket = e.AcceptSocket;
518 if (acceptSocket != null) {
519 if (acceptSocket.IsBound || acceptSocket.Connected)
520 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
525 w.Init (this, e, SocketOperation.Accept);
528 readQ.Enqueue (e.Worker);
532 socket_pool_queue (Worker.Dispatcher, w.result);
536 // Creates a new system socket, returning the handle
537 [MethodImplAttribute(MethodImplOptions.InternalCall)]
538 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
540 public Socket Accept() {
541 if (disposed && closed)
542 throw new ObjectDisposedException (GetType ().ToString ());
545 IntPtr sock = (IntPtr) (-1);
546 blocking_thread = Thread.CurrentThread;
548 sock = Accept_internal(socket, out error, blocking);
549 } catch (ThreadAbortException) {
551 Thread.ResetAbort ();
552 error = (int) SocketError.Interrupted;
555 blocking_thread = null;
559 throw new SocketException (error);
561 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
562 this.ProtocolType, sock);
564 accepted.seed_endpoint = this.seed_endpoint;
565 accepted.Blocking = this.Blocking;
569 internal void Accept (Socket acceptSocket)
571 if (disposed && closed)
572 throw new ObjectDisposedException (GetType ().ToString ());
575 IntPtr sock = (IntPtr)(-1);
576 blocking_thread = Thread.CurrentThread;
579 sock = Accept_internal (socket, out error, blocking);
580 } catch (ThreadAbortException) {
582 Thread.ResetAbort ();
583 error = (int)SocketError.Interrupted;
586 blocking_thread = null;
590 throw new SocketException (error);
592 acceptSocket.address_family = this.AddressFamily;
593 acceptSocket.socket_type = this.SocketType;
594 acceptSocket.protocol_type = this.ProtocolType;
595 acceptSocket.socket = sock;
596 acceptSocket.connected = true;
597 acceptSocket.seed_endpoint = this.seed_endpoint;
598 acceptSocket.Blocking = this.Blocking;
600 /* FIXME: figure out what if anything else
605 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
607 if (disposed && closed)
608 throw new ObjectDisposedException (GetType ().ToString ());
610 if (!isbound || !islistening)
611 throw new InvalidOperationException ();
613 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
616 readQ.Enqueue (req.Worker);
620 socket_pool_queue (Worker.Dispatcher, req);
624 public IAsyncResult BeginAccept (int receiveSize,
625 AsyncCallback callback,
628 if (disposed && closed)
629 throw new ObjectDisposedException (GetType ().ToString ());
632 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
634 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
635 req.Buffer = new byte[receiveSize];
637 req.Size = receiveSize;
638 req.SockFlags = SocketFlags.None;
641 readQ.Enqueue (req.Worker);
645 socket_pool_queue (Worker.Dispatcher, req);
649 public IAsyncResult BeginAccept (Socket acceptSocket,
651 AsyncCallback callback,
654 if (disposed && closed)
655 throw new ObjectDisposedException (GetType ().ToString ());
658 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
660 if (acceptSocket != null) {
661 if (acceptSocket.disposed && acceptSocket.closed)
662 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
664 if (acceptSocket.IsBound)
665 throw new InvalidOperationException ();
667 /* For some reason the MS runtime
668 * barfs if the new socket is not TCP,
669 * even though it's just about to blow
670 * away all those parameters
672 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
673 throw new SocketException ((int)SocketError.InvalidArgument);
676 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
677 req.Buffer = new byte[receiveSize];
679 req.Size = receiveSize;
680 req.SockFlags = SocketFlags.None;
681 req.AcceptSocket = acceptSocket;
684 readQ.Enqueue (req.Worker);
688 socket_pool_queue (Worker.Dispatcher, req);
692 public IAsyncResult BeginConnect (IPAddress address, int port,
693 AsyncCallback callback,
696 if (disposed && closed)
697 throw new ObjectDisposedException (GetType ().ToString ());
700 throw new ArgumentNullException ("address");
702 if (address.ToString ().Length == 0)
703 throw new ArgumentException ("The length of the IP address is zero");
705 if (port <= 0 || port > 65535)
706 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
709 throw new InvalidOperationException ();
711 IPEndPoint iep = new IPEndPoint (address, port);
712 return(BeginConnect (iep, callback, state));
715 public IAsyncResult BeginConnect (string host, int port,
716 AsyncCallback callback,
719 if (disposed && closed)
720 throw new ObjectDisposedException (GetType ().ToString ());
723 throw new ArgumentNullException ("host");
725 if (address_family != AddressFamily.InterNetwork &&
726 address_family != AddressFamily.InterNetworkV6)
727 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
729 if (port <= 0 || port > 65535)
730 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
733 throw new InvalidOperationException ();
735 return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
738 public IAsyncResult BeginDisconnect (bool reuseSocket,
739 AsyncCallback callback,
742 if (disposed && closed)
743 throw new ObjectDisposedException (GetType ().ToString ());
745 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
746 req.ReuseSocket = reuseSocket;
747 socket_pool_queue (Worker.Dispatcher, req);
751 void CheckRange(byte[] buffer, int offset, int size)
753 if (offset < 0 || offset > buffer.Length)
754 throw new ArgumentOutOfRangeException ("offset");
756 if (size < 0 || size > buffer.Length - offset)
757 throw new ArgumentOutOfRangeException ("size");
760 public IAsyncResult BeginReceive(byte[] buffer, int offset,
762 SocketFlags socket_flags,
763 AsyncCallback callback,
766 if (disposed && closed)
767 throw new ObjectDisposedException (GetType ().ToString ());
770 throw new ArgumentNullException ("buffer");
772 CheckRange(buffer, offset, size);
774 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
778 req.SockFlags = socket_flags;
781 readQ.Enqueue (req.Worker);
785 socket_pool_queue (Worker.Dispatcher, req);
789 public IAsyncResult BeginReceive (byte[] buffer, int offset,
790 int size, SocketFlags flags,
791 out SocketError error,
792 AsyncCallback callback,
795 /* As far as I can tell from the docs and from
796 * experimentation, a pointer to the
797 * SocketError parameter is not supposed to be
798 * saved for the async parts. And as we don't
799 * set any socket errors in the setup code, we
800 * just have to set it to Success.
802 error = SocketError.Success;
803 return (BeginReceive (buffer, offset, size, flags, callback, state));
806 [CLSCompliant (false)]
807 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
808 SocketFlags socketFlags,
809 AsyncCallback callback,
812 if (disposed && closed)
813 throw new ObjectDisposedException (GetType ().ToString ());
816 throw new ArgumentNullException ("buffers");
818 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
819 req.Buffers = buffers;
820 req.SockFlags = socketFlags;
823 readQ.Enqueue (req.Worker);
827 socket_pool_queue (Worker.Dispatcher, req);
831 [CLSCompliant (false)]
832 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
833 SocketFlags socketFlags,
834 out SocketError errorCode,
835 AsyncCallback callback,
838 /* I assume the same SocketError semantics as
841 errorCode = SocketError.Success;
842 return (BeginReceive (buffers, socketFlags, callback, state));
845 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
847 SocketFlags socket_flags,
848 ref EndPoint remote_end,
849 AsyncCallback callback,
851 if (disposed && closed)
852 throw new ObjectDisposedException (GetType ().ToString ());
855 throw new ArgumentNullException ("buffer");
857 if (remote_end == null)
858 throw new ArgumentNullException ("remote_end");
860 CheckRange (buffer, offset, size);
862 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
866 req.SockFlags = socket_flags;
867 req.EndPoint = remote_end;
870 readQ.Enqueue (req.Worker);
874 socket_pool_queue (Worker.Dispatcher, req);
879 public IAsyncResult BeginReceiveMessageFrom (
880 byte[] buffer, int offset, int size,
881 SocketFlags socketFlags, ref EndPoint remoteEP,
882 AsyncCallback callback, object state)
884 if (disposed && closed)
885 throw new ObjectDisposedException (GetType ().ToString ());
888 throw new ArgumentNullException ("buffer");
890 if (remoteEP == null)
891 throw new ArgumentNullException ("remoteEP");
893 CheckRange (bufer, offset, size);
895 throw new NotImplementedException ();
898 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
899 AsyncCallback callback, object state)
901 if (disposed && closed)
902 throw new ObjectDisposedException (GetType ().ToString ());
905 throw new ArgumentNullException ("buffer");
907 CheckRange (buffer, offset, size);
910 throw new SocketException ((int)SocketError.NotConnected);
912 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
916 req.SockFlags = socket_flags;
919 writeQ.Enqueue (req.Worker);
920 count = writeQ.Count;
923 socket_pool_queue (Worker.Dispatcher, req);
927 public IAsyncResult BeginSend (byte[] buffer, int offset,
929 SocketFlags socketFlags,
930 out SocketError errorCode,
931 AsyncCallback callback,
935 errorCode = SocketError.NotConnected;
936 throw new SocketException ((int)errorCode);
939 errorCode = SocketError.Success;
941 return (BeginSend (buffer, offset, size, socketFlags, callback,
945 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
946 SocketFlags socketFlags,
947 AsyncCallback callback,
950 if (disposed && closed)
951 throw new ObjectDisposedException (GetType ().ToString ());
954 throw new ArgumentNullException ("buffers");
957 throw new SocketException ((int)SocketError.NotConnected);
959 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
960 req.Buffers = buffers;
961 req.SockFlags = socketFlags;
964 writeQ.Enqueue (req.Worker);
965 count = writeQ.Count;
968 socket_pool_queue (Worker.Dispatcher, req);
972 [CLSCompliant (false)]
973 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
974 SocketFlags socketFlags,
975 out SocketError errorCode,
976 AsyncCallback callback,
980 errorCode = SocketError.NotConnected;
981 throw new SocketException ((int)errorCode);
984 errorCode = SocketError.Success;
985 return (BeginSend (buffers, socketFlags, callback, state));
988 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
990 sealed class SendFileAsyncResult : IAsyncResult {
994 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
1000 public object AsyncState {
1001 get { return ares.AsyncState; }
1004 public WaitHandle AsyncWaitHandle {
1005 get { return ares.AsyncWaitHandle; }
1008 public bool CompletedSynchronously {
1009 get { return ares.CompletedSynchronously; }
1012 public bool IsCompleted {
1013 get { return ares.IsCompleted; }
1016 public SendFileHandler Delegate {
1020 public IAsyncResult Original {
1021 get { return ares; }
1025 public IAsyncResult BeginSendFile (string fileName,
1026 AsyncCallback callback,
1029 if (disposed && closed)
1030 throw new ObjectDisposedException (GetType ().ToString ());
1033 throw new NotSupportedException ();
1035 if (!File.Exists (fileName))
1036 throw new FileNotFoundException ();
1038 return BeginSendFile (fileName, null, null, 0, callback, state);
1041 public IAsyncResult BeginSendFile (string fileName,
1044 TransmitFileOptions flags,
1045 AsyncCallback callback,
1048 if (disposed && closed)
1049 throw new ObjectDisposedException (GetType ().ToString ());
1052 throw new NotSupportedException ();
1054 if (!File.Exists (fileName))
1055 throw new FileNotFoundException ();
1057 SendFileHandler d = new SendFileHandler (SendFile);
1058 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
1061 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1063 SocketFlags socket_flags,
1064 EndPoint remote_end,
1065 AsyncCallback callback,
1067 if (disposed && closed)
1068 throw new ObjectDisposedException (GetType ().ToString ());
1071 throw new ArgumentNullException ("buffer");
1073 CheckRange (buffer, offset, size);
1075 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1076 req.Buffer = buffer;
1077 req.Offset = offset;
1079 req.SockFlags = socket_flags;
1080 req.EndPoint = remote_end;
1083 writeQ.Enqueue (req.Worker);
1084 count = writeQ.Count;
1087 socket_pool_queue (Worker.Dispatcher, req);
1091 // Creates a new system socket, returning the handle
1092 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1093 private extern static void Bind_internal(IntPtr sock,
1097 public void Bind(EndPoint local_end) {
1098 if (disposed && closed)
1099 throw new ObjectDisposedException (GetType ().ToString ());
1101 if (local_end == null)
1102 throw new ArgumentNullException("local_end");
1106 Bind_internal(socket, local_end.Serialize(), out error);
1108 throw new SocketException (error);
1112 seed_endpoint = local_end;
1115 public void Connect (IPAddress address, int port)
1117 Connect (new IPEndPoint (address, port));
1120 public void Connect (IPAddress[] addresses, int port)
1122 if (disposed && closed)
1123 throw new ObjectDisposedException (GetType ().ToString ());
1125 if (addresses == null)
1126 throw new ArgumentNullException ("addresses");
1128 if (this.AddressFamily != AddressFamily.InterNetwork &&
1129 this.AddressFamily != AddressFamily.InterNetworkV6)
1130 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1133 throw new InvalidOperationException ();
1135 /* FIXME: do non-blocking sockets Poll here? */
1137 foreach (IPAddress address in addresses) {
1138 IPEndPoint iep = new IPEndPoint (address, port);
1139 SocketAddress serial = iep.Serialize ();
1141 Connect_internal (socket, serial, out error);
1145 seed_endpoint = iep;
1147 } else if (error != (int)SocketError.InProgress &&
1148 error != (int)SocketError.WouldBlock) {
1153 Poll (-1, SelectMode.SelectWrite);
1154 error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1158 seed_endpoint = iep;
1164 throw new SocketException (error);
1167 public void Connect (string host, int port)
1169 IPAddress [] addresses = Dns.GetHostAddresses (host);
1170 Connect (addresses, port);
1174 public bool DisconnectAsync (SocketAsyncEventArgs e)
1176 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1177 if (disposed && closed)
1178 throw new ObjectDisposedException (GetType ().ToString ());
1181 e.Worker.Init (this, e, SocketOperation.Disconnect);
1182 socket_pool_queue (Worker.Dispatcher, e.Worker.result);
1187 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1188 extern static void Disconnect_internal(IntPtr sock, bool reuse, out int error);
1190 /* According to the docs, the MS runtime will throw
1191 * PlatformNotSupportedException if the platform is
1192 * newer than w2k. We should be able to cope...
1194 public void Disconnect (bool reuseSocket)
1196 if (disposed && closed)
1197 throw new ObjectDisposedException (GetType ().ToString ());
1201 Disconnect_internal (socket, reuseSocket, out error);
1205 /* ERROR_NOT_SUPPORTED */
1206 throw new PlatformNotSupportedException ();
1208 throw new SocketException (error);
1215 /* Do managed housekeeping here... */
1220 [MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
1221 public SocketInformation DuplicateAndClose (int targetProcessId)
1223 var si = new SocketInformation ();
1225 (islistening ? SocketInformationOptions.Listening : 0) |
1226 (connected ? SocketInformationOptions.Connected : 0) |
1227 (blocking ? 0 : SocketInformationOptions.NonBlocking) |
1228 (useoverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
1230 si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket);
1231 socket = (IntPtr) (-1);
1237 public Socket EndAccept (IAsyncResult result)
1242 return(EndAccept (out buffer, out bytes, result));
1245 public Socket EndAccept (out byte[] buffer, IAsyncResult asyncResult)
1248 return(EndAccept (out buffer, out bytes, asyncResult));
1251 public Socket EndAccept (out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
1253 if (disposed && closed)
1254 throw new ObjectDisposedException (GetType ().ToString ());
1256 if (asyncResult == null)
1257 throw new ArgumentNullException ("asyncResult");
1259 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1261 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1263 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1264 throw InvalidAsyncOp ("EndAccept");
1265 if (!asyncResult.IsCompleted)
1266 asyncResult.AsyncWaitHandle.WaitOne ();
1268 req.CheckIfThrowDelayedException ();
1270 buffer = req.Buffer;
1271 bytesTransferred = req.Total;
1276 public void EndConnect (IAsyncResult result)
1278 if (disposed && closed)
1279 throw new ObjectDisposedException (GetType ().ToString ());
1282 throw new ArgumentNullException ("result");
1284 SocketAsyncResult req = result as SocketAsyncResult;
1286 throw new ArgumentException ("Invalid IAsyncResult", "result");
1288 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1289 throw InvalidAsyncOp ("EndConnect");
1290 if (!result.IsCompleted)
1291 result.AsyncWaitHandle.WaitOne();
1293 req.CheckIfThrowDelayedException();
1297 public void EndDisconnect (IAsyncResult asyncResult)
1299 if (disposed && closed)
1300 throw new ObjectDisposedException (GetType ().ToString ());
1302 if (asyncResult == null)
1303 throw new ArgumentNullException ("asyncResult");
1305 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1307 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1309 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1310 throw InvalidAsyncOp ("EndDisconnect");
1311 if (!asyncResult.IsCompleted)
1312 asyncResult.AsyncWaitHandle.WaitOne ();
1314 req.CheckIfThrowDelayedException ();
1319 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
1320 ref SocketFlags socketFlags,
1321 ref EndPoint endPoint,
1322 out IPPacketInformation ipPacketInformation)
1324 if (disposed && closed)
1325 throw new ObjectDisposedException (GetType ().ToString ());
1327 if (asyncResult == null)
1328 throw new ArgumentNullException ("asyncResult");
1330 if (endPoint == null)
1331 throw new ArgumentNullException ("endPoint");
1333 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1335 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1337 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1338 throw InvalidAsyncOp ("EndReceiveMessageFrom");
1339 throw new NotImplementedException ();
1342 public void EndSendFile (IAsyncResult asyncResult)
1344 if (disposed && closed)
1345 throw new ObjectDisposedException (GetType ().ToString ());
1347 if (asyncResult == null)
1348 throw new ArgumentNullException ("asyncResult");
1350 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
1352 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1354 ares.Delegate.EndInvoke (ares.Original);
1358 public int EndSendTo (IAsyncResult result)
1360 if (disposed && closed)
1361 throw new ObjectDisposedException (GetType ().ToString ());
1364 throw new ArgumentNullException ("result");
1366 SocketAsyncResult req = result as SocketAsyncResult;
1368 throw new ArgumentException ("Invalid IAsyncResult", "result");
1370 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1371 throw InvalidAsyncOp ("EndSendTo");
1372 if (!result.IsCompleted)
1373 result.AsyncWaitHandle.WaitOne();
1375 req.CheckIfThrowDelayedException();
1380 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1381 private extern static void GetSocketOption_arr_internal(IntPtr socket,
1382 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
1385 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
1387 if (disposed && closed)
1388 throw new ObjectDisposedException (GetType ().ToString ());
1390 if (optionValue == null)
1391 throw new SocketException ((int) SocketError.Fault,
1392 "Error trying to dereference an invalid pointer");
1396 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
1399 throw new SocketException (error);
1402 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
1404 if (disposed && closed)
1405 throw new ObjectDisposedException (GetType ().ToString ());
1407 byte[] byte_val=new byte[length];
1410 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
1413 throw new SocketException (error);
1418 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1419 // common options between UNIX and Winsock are FIONREAD,
1420 // FIONBIO and SIOCATMARK. Anything else will depend on the
1421 // system except SIO_KEEPALIVE_VALS which is properly handled
1422 // on both windows and linux.
1423 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1424 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
1425 byte [] output, out int error);
1427 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1430 throw new ObjectDisposedException (GetType ().ToString ());
1433 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
1437 throw new SocketException (error);
1440 throw new InvalidOperationException ("Must use Blocking property instead.");
1445 public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
1447 return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
1450 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1451 private extern static void Listen_internal(IntPtr sock, int backlog, out int error);
1453 public void Listen (int backlog)
1455 if (disposed && closed)
1456 throw new ObjectDisposedException (GetType ().ToString ());
1459 throw new SocketException ((int)SocketError.InvalidArgument);
1462 Listen_internal(socket, backlog, out error);
1465 throw new SocketException (error);
1470 public bool Poll (int time_us, SelectMode mode)
1472 if (disposed && closed)
1473 throw new ObjectDisposedException (GetType ().ToString ());
1475 if (mode != SelectMode.SelectRead &&
1476 mode != SelectMode.SelectWrite &&
1477 mode != SelectMode.SelectError)
1478 throw new NotSupportedException ("'mode' parameter is not valid.");
1481 bool result = Poll_internal (socket, mode, time_us, out error);
1483 throw new SocketException (error);
1485 if (mode == SelectMode.SelectWrite && result && !connected) {
1486 /* Update the connected state; for
1487 * non-blocking Connect()s this is
1488 * when we can find out that the
1489 * connect succeeded.
1491 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
1499 public int Receive (byte [] buffer)
1501 if (disposed && closed)
1502 throw new ObjectDisposedException (GetType ().ToString ());
1505 throw new ArgumentNullException ("buffer");
1509 int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
1511 if (error != SocketError.Success)
1512 throw new SocketException ((int) error);
1517 public int Receive (byte [] buffer, SocketFlags flags)
1519 if (disposed && closed)
1520 throw new ObjectDisposedException (GetType ().ToString ());
1523 throw new ArgumentNullException ("buffer");
1527 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
1529 if (error != SocketError.Success) {
1530 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1531 throw new SocketException ((int) error, "Operation timed out.");
1532 throw new SocketException ((int) error);
1538 public int Receive (byte [] buffer, int size, SocketFlags flags)
1540 if (disposed && closed)
1541 throw new ObjectDisposedException (GetType ().ToString ());
1544 throw new ArgumentNullException ("buffer");
1546 CheckRange (buffer, 0, size);
1550 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
1552 if (error != SocketError.Success) {
1553 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1554 throw new SocketException ((int) error, "Operation timed out.");
1555 throw new SocketException ((int) error);
1561 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
1563 if (disposed && closed)
1564 throw new ObjectDisposedException (GetType ().ToString ());
1567 throw new ArgumentNullException ("buffer");
1569 CheckRange (buffer, offset, size);
1573 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
1575 if (error != SocketError.Success) {
1576 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1577 throw new SocketException ((int) error, "Operation timed out.");
1578 throw new SocketException ((int) error);
1584 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
1586 if (disposed && closed)
1587 throw new ObjectDisposedException (GetType ().ToString ());
1590 throw new ArgumentNullException ("buffer");
1592 CheckRange (buffer, offset, size);
1594 return Receive_nochecks (buffer, offset, size, flags, out error);
1598 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
1600 if (disposed && closed)
1601 throw new ObjectDisposedException (GetType ().ToString ());
1603 // We do not support recv into multiple buffers yet
1604 if (e.BufferList != null)
1605 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1606 if (e.RemoteEndPoint == null)
1607 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1610 e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
1611 SocketAsyncResult res = e.Worker.result;
1612 res.Buffer = e.Buffer;
1613 res.Offset = e.Offset;
1615 res.EndPoint = e.RemoteEndPoint;
1616 res.SockFlags = e.SocketFlags;
1617 Worker worker = new Worker (e);
1620 readQ.Enqueue (worker);
1621 count = readQ.Count;
1624 socket_pool_queue (Worker.Dispatcher, res);
1629 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
1631 if (disposed && closed)
1632 throw new ObjectDisposedException (GetType ().ToString ());
1635 throw new ArgumentNullException ("buffer");
1637 if (remoteEP == null)
1638 throw new ArgumentNullException ("remoteEP");
1640 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
1643 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
1645 if (disposed && closed)
1646 throw new ObjectDisposedException (GetType ().ToString ());
1649 throw new ArgumentNullException ("buffer");
1651 if (remoteEP == null)
1652 throw new ArgumentNullException ("remoteEP");
1654 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
1657 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
1658 ref EndPoint remoteEP)
1660 if (disposed && closed)
1661 throw new ObjectDisposedException (GetType ().ToString ());
1664 throw new ArgumentNullException ("buffer");
1666 if (remoteEP == null)
1667 throw new ArgumentNullException ("remoteEP");
1669 if (size < 0 || size > buffer.Length)
1670 throw new ArgumentOutOfRangeException ("size");
1672 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
1675 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1676 private extern static int RecvFrom_internal(IntPtr sock,
1681 ref SocketAddress sockaddr,
1684 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
1685 ref EndPoint remoteEP)
1687 if (disposed && closed)
1688 throw new ObjectDisposedException (GetType ().ToString ());
1691 throw new ArgumentNullException ("buffer");
1693 if (remoteEP == null)
1694 throw new ArgumentNullException ("remoteEP");
1696 CheckRange (buffer, offset, size);
1698 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
1701 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1702 ref EndPoint remote_end)
1705 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
1708 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
1709 ref EndPoint remote_end, bool throwOnError, out int error)
1711 SocketAddress sockaddr = remote_end.Serialize();
1712 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1713 SocketError err = (SocketError) error;
1715 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
1717 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
1719 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
1720 error = (int) SocketError.TimedOut;
1725 throw new SocketException (error);
1732 // If sockaddr is null then we're a connection
1733 // oriented protocol and should ignore the
1734 // remote_end parameter (see MSDN
1735 // documentation for Socket.ReceiveFrom(...) )
1737 if ( sockaddr != null ) {
1738 // Stupidly, EndPoint.Create() is an
1740 remote_end = remote_end.Create (sockaddr);
1743 seed_endpoint = remote_end;
1748 [MonoTODO ("Not implemented")]
1749 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
1751 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1752 if (disposed && closed)
1753 throw new ObjectDisposedException (GetType ().ToString ());
1755 throw new NotImplementedException ();
1758 [MonoTODO ("Not implemented")]
1759 public int ReceiveMessageFrom (byte[] buffer, int offset,
1761 ref SocketFlags socketFlags,
1762 ref EndPoint remoteEP,
1763 out IPPacketInformation ipPacketInformation)
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 /* FIXME: figure out how we get hold of the
1777 * IPPacketInformation
1779 throw new NotImplementedException ();
1782 [MonoTODO ("Not implemented")]
1783 public bool SendPacketsAsync (SocketAsyncEventArgs e)
1785 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1787 if (disposed && closed)
1788 throw new ObjectDisposedException (GetType ().ToString ());
1790 throw new NotImplementedException ();
1793 public int Send (byte [] buf)
1795 if (disposed && closed)
1796 throw new ObjectDisposedException (GetType ().ToString ());
1799 throw new ArgumentNullException ("buf");
1803 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
1805 if (error != SocketError.Success)
1806 throw new SocketException ((int) error);
1811 public int Send (byte [] buf, SocketFlags flags)
1813 if (disposed && closed)
1814 throw new ObjectDisposedException (GetType ().ToString ());
1817 throw new ArgumentNullException ("buf");
1821 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
1823 if (error != SocketError.Success)
1824 throw new SocketException ((int) error);
1829 public int Send (byte [] buf, int size, SocketFlags flags)
1831 if (disposed && closed)
1832 throw new ObjectDisposedException (GetType ().ToString ());
1835 throw new ArgumentNullException ("buf");
1837 CheckRange (buf, 0, size);
1841 int ret = Send_nochecks (buf, 0, size, flags, out error);
1843 if (error != SocketError.Success)
1844 throw new SocketException ((int) error);
1849 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
1851 if (disposed && closed)
1852 throw new ObjectDisposedException (GetType ().ToString ());
1855 throw new ArgumentNullException ("buffer");
1857 CheckRange (buf, offset, size);
1861 int ret = Send_nochecks (buf, offset, size, flags, out error);
1863 if (error != SocketError.Success)
1864 throw new SocketException ((int) error);
1869 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
1871 if (disposed && closed)
1872 throw new ObjectDisposedException (GetType ().ToString ());
1875 throw new ArgumentNullException ("buffer");
1877 CheckRange (buf, offset, size);
1879 return Send_nochecks (buf, offset, size, flags, out error);
1882 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1883 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
1885 public void SendFile (string fileName)
1887 if (disposed && closed)
1888 throw new ObjectDisposedException (GetType ().ToString ());
1891 throw new NotSupportedException ();
1894 throw new InvalidOperationException ();
1896 SendFile (fileName, null, null, 0);
1899 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
1901 if (disposed && closed)
1902 throw new ObjectDisposedException (GetType ().ToString ());
1905 throw new NotSupportedException ();
1908 throw new InvalidOperationException ();
1910 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
1911 SocketException exc = new SocketException ();
1912 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
1913 throw new FileNotFoundException ();
1919 public bool SendToAsync (SocketAsyncEventArgs e)
1921 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1923 if (disposed && closed)
1924 throw new ObjectDisposedException (GetType ().ToString ());
1925 if (e.BufferList != null)
1926 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1927 if (e.RemoteEndPoint == null)
1928 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1931 e.Worker.Init (this, e, SocketOperation.SendTo);
1932 SocketAsyncResult res = e.Worker.result;
1933 res.Buffer = e.Buffer;
1934 res.Offset = e.Offset;
1936 res.SockFlags = e.SocketFlags;
1937 res.EndPoint = e.RemoteEndPoint;
1938 Worker worker = new Worker (e);
1941 writeQ.Enqueue (worker);
1942 count = writeQ.Count;
1945 socket_pool_queue (Worker.Dispatcher, res);
1950 public int SendTo (byte [] buffer, EndPoint remote_end)
1952 if (disposed && closed)
1953 throw new ObjectDisposedException (GetType ().ToString ());
1956 throw new ArgumentNullException ("buffer");
1958 if (remote_end == null)
1959 throw new ArgumentNullException ("remote_end");
1961 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
1964 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
1966 if (disposed && closed)
1967 throw new ObjectDisposedException (GetType ().ToString ());
1970 throw new ArgumentNullException ("buffer");
1972 if (remote_end == null)
1973 throw new ArgumentNullException ("remote_end");
1975 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
1978 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
1980 if (disposed && closed)
1981 throw new ObjectDisposedException (GetType ().ToString ());
1984 throw new ArgumentNullException ("buffer");
1986 if (remote_end == null)
1987 throw new ArgumentNullException ("remote_end");
1989 CheckRange (buffer, 0, size);
1991 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
1994 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1995 private extern static int SendTo_internal(IntPtr sock,
2003 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2004 EndPoint remote_end)
2006 if (disposed && closed)
2007 throw new ObjectDisposedException (GetType ().ToString ());
2010 throw new ArgumentNullException ("buffer");
2012 if (remote_end == null)
2013 throw new ArgumentNullException("remote_end");
2015 CheckRange (buffer, offset, size);
2017 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2020 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2021 EndPoint remote_end)
2023 SocketAddress sockaddr = remote_end.Serialize ();
2027 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2029 SocketError err = (SocketError) error;
2031 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2034 throw new SocketException (error);
2039 seed_endpoint = remote_end;
2044 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2046 if (disposed && closed)
2047 throw new ObjectDisposedException (GetType ().ToString ());
2049 // I'd throw an ArgumentNullException, but this is what MS does.
2050 if (optionValue == null)
2051 throw new SocketException ((int) SocketError.Fault,
2052 "Error trying to dereference an invalid pointer");
2056 SetSocketOption_internal (socket, optionLevel, optionName, null,
2057 optionValue, 0, out error);
2060 if (error == (int) SocketError.InvalidArgument)
2061 throw new ArgumentException ();
2062 throw new SocketException (error);
2066 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
2068 if (disposed && closed)
2069 throw new ObjectDisposedException (GetType ().ToString ());
2071 // NOTE: if a null is passed, the byte[] overload is used instead...
2072 if (optionValue == null)
2073 throw new ArgumentNullException("optionValue");
2077 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
2078 LingerOption linger = optionValue as LingerOption;
2080 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
2081 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
2082 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2083 MulticastOption multicast = optionValue as MulticastOption;
2084 if (multicast == null)
2085 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
2086 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2087 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2088 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
2089 if (multicast == null)
2090 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
2091 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2093 throw new ArgumentException ("Invalid value specified.", "optionValue");
2097 if (error == (int) SocketError.InvalidArgument)
2098 throw new ArgumentException ();
2099 throw new SocketException (error);
2103 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
2105 if (disposed && closed)
2106 throw new ObjectDisposedException (GetType ().ToString ());
2109 int int_val = (optionValue) ? 1 : 0;
2110 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
2112 if (error == (int) SocketError.InvalidArgument)
2113 throw new ArgumentException ();
2114 throw new SocketException (error);