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;
48 using System.Net.NetworkInformation;
50 namespace System.Net.Sockets
52 public partial class Socket : IDisposable
54 private bool islistening;
55 private bool useoverlappedIO;
56 private const int SOCKET_CLOSED = 10004;
58 static void AddSockets (List<Socket> sockets, IList list, string name)
61 foreach (Socket sock in list) {
62 if (sock == null) // MS throws a NullRef
63 throw new ArgumentNullException ("name", "Contains a null element");
71 [MethodImplAttribute(MethodImplOptions.InternalCall)]
72 private extern static void Select_internal (ref Socket [] sockets,
76 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
78 var list = new List<Socket> ();
79 AddSockets (list, checkRead, "checkRead");
80 AddSockets (list, checkWrite, "checkWrite");
81 AddSockets (list, checkError, "checkError");
83 if (list.Count == 3) {
84 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
85 "All the lists are null or empty.");
90 * The 'sockets' array contains: READ socket 0-n, null,
91 * WRITE socket 0-n, null,
92 * ERROR socket 0-n, null
94 Socket [] sockets = list.ToArray ();
95 Select_internal (ref sockets, microSeconds, out error);
98 throw new SocketException (error);
100 if (sockets == null) {
101 if (checkRead != null)
103 if (checkWrite != null)
105 if (checkError != null)
111 int count = sockets.Length;
112 IList currentList = checkRead;
114 for (int i = 0; i < count; i++) {
115 Socket sock = sockets [i];
116 if (sock == null) { // separator
117 if (currentList != null) {
118 // Remove non-signaled sockets after the current one
119 int to_remove = currentList.Count - currentIdx;
120 for (int k = 0; k < to_remove; k++)
121 currentList.RemoveAt (currentIdx);
123 currentList = (mode == 0) ? checkWrite : checkError;
129 if (mode == 1 && currentList == checkWrite && !sock.connected) {
130 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
131 sock.connected = true;
134 // Remove non-signaled sockets before the current one
135 //int max = currentList.Count;
136 while (((Socket) currentList [currentIdx]) != sock) {
137 currentList.RemoveAt (currentIdx);
143 // private constructor used by Accept, which already
144 // has a socket handle to use
145 internal Socket(AddressFamily family, SocketType type,
146 ProtocolType proto, IntPtr sock)
148 address_family=family;
156 private void SocketDefaults ()
159 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
160 address_family == AddressFamily.InterNetworkV6 */) {
161 /* This is the default, but it
162 * probably has nasty side
163 * effects on Linux, as the
164 * socket option is kludged by
165 * turning on or off PMTU
168 this.DontFragment = false;
172 // Microsoft sets these to 8192, but we are going to keep them
173 // both to the OS defaults as these have a big performance impact.
174 // on WebClient performance.
176 //this.ReceiveBufferSize = 8192;
177 //this.SendBufferSize = 8192;
178 } catch (SocketException) {
183 public Socket (SocketInformation socketInformation)
185 var options = socketInformation.Options;
186 islistening = (options & SocketInformationOptions.Listening) != 0;
187 connected = (options & SocketInformationOptions.Connected) != 0;
188 blocking = (options & SocketInformationOptions.NonBlocking) == 0;
189 useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
191 var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
193 address_family = (AddressFamily) (int) result [0];
194 socket_type = (SocketType) (int) result [1];
195 protocol_type = (ProtocolType) (int) result [2];
196 isbound = (ProtocolType) (int) result [3] != 0;
197 socket = (IntPtr) (long) result [4];
203 // Returns the amount of data waiting to be read on socket
204 [MethodImplAttribute(MethodImplOptions.InternalCall)]
205 private extern static int Available_internal(IntPtr socket, out int error);
208 public int Available {
210 if (disposed && closed)
211 throw new ObjectDisposedException (GetType ().ToString ());
215 ret = Available_internal(socket, out error);
218 throw new SocketException (error);
225 public bool DontFragment {
227 if (disposed && closed) {
228 throw new ObjectDisposedException (GetType ().ToString ());
233 if (address_family == AddressFamily.InterNetwork) {
234 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
235 } else if (address_family == AddressFamily.InterNetworkV6) {
236 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
238 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
241 return(dontfragment);
244 if (disposed && closed) {
245 throw new ObjectDisposedException (GetType ().ToString ());
248 if (address_family == AddressFamily.InterNetwork) {
249 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
250 } else if (address_family == AddressFamily.InterNetworkV6) {
251 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
253 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
258 public bool EnableBroadcast {
260 if (disposed && closed) {
261 throw new ObjectDisposedException (GetType ().ToString ());
264 if (protocol_type != ProtocolType.Udp) {
265 throw new SocketException ((int)SocketError.ProtocolOption);
268 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
271 if (disposed && closed) {
272 throw new ObjectDisposedException (GetType ().ToString ());
275 if (protocol_type != ProtocolType.Udp) {
276 throw new SocketException ((int)SocketError.ProtocolOption);
279 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
283 public bool ExclusiveAddressUse {
285 if (disposed && closed) {
286 throw new ObjectDisposedException (GetType ().ToString ());
289 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
292 if (disposed && closed) {
293 throw new ObjectDisposedException (GetType ().ToString ());
296 throw new InvalidOperationException ("Bind has already been called for this socket");
299 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
303 public bool IsBound {
309 public LingerOption LingerState {
311 if (disposed && closed) {
312 throw new ObjectDisposedException (GetType ().ToString ());
315 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
318 if (disposed && closed) {
319 throw new ObjectDisposedException (GetType ().ToString ());
322 SetSocketOption (SocketOptionLevel.Socket,
323 SocketOptionName.Linger,
328 public bool MulticastLoopback {
330 if (disposed && closed) {
331 throw new ObjectDisposedException (GetType ().ToString ());
334 /* Even though this option can be set
335 * for TCP sockets on Linux, throw
336 * this exception anyway to be
337 * compatible (the MSDN docs say
338 * "Setting this property on a
339 * Transmission Control Protocol (TCP)
340 * socket will have no effect." but
341 * the MS runtime throws the
344 if (protocol_type == ProtocolType.Tcp) {
345 throw new SocketException ((int)SocketError.ProtocolOption);
348 bool multicastloopback;
350 if (address_family == AddressFamily.InterNetwork) {
351 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
352 } else if (address_family == AddressFamily.InterNetworkV6) {
353 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
355 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
358 return(multicastloopback);
361 if (disposed && closed) {
362 throw new ObjectDisposedException (GetType ().ToString ());
365 /* Even though this option can be set
366 * for TCP sockets on Linux, throw
367 * this exception anyway to be
368 * compatible (the MSDN docs say
369 * "Setting this property on a
370 * Transmission Control Protocol (TCP)
371 * socket will have no effect." but
372 * the MS runtime throws the
375 if (protocol_type == ProtocolType.Tcp) {
376 throw new SocketException ((int)SocketError.ProtocolOption);
379 if (address_family == AddressFamily.InterNetwork) {
380 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
381 } else if (address_family == AddressFamily.InterNetworkV6) {
382 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
384 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
390 [MonoTODO ("This doesn't do anything on Mono yet")]
391 public bool UseOnlyOverlappedIO {
393 return(useoverlappedIO);
396 useoverlappedIO = value;
400 public IntPtr Handle {
407 // Returns the local endpoint details in addr and port
408 [MethodImplAttribute(MethodImplOptions.InternalCall)]
409 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
412 // Wish: support non-IP endpoints.
413 public EndPoint LocalEndPoint {
415 if (disposed && closed)
416 throw new ObjectDisposedException (GetType ().ToString ());
419 * If the seed EndPoint is null, Connect, Bind,
420 * etc has not yet been called. MS returns null
423 if (seed_endpoint == null)
429 sa=LocalEndPoint_internal(socket, (int) address_family, out error);
432 throw new SocketException (error);
434 return seed_endpoint.Create (sa);
438 public SocketType SocketType {
444 public int SendTimeout {
446 if (disposed && closed)
447 throw new ObjectDisposedException (GetType ().ToString ());
449 return (int)GetSocketOption(
450 SocketOptionLevel.Socket,
451 SocketOptionName.SendTimeout);
454 if (disposed && closed)
455 throw new ObjectDisposedException (GetType ().ToString ());
458 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
460 /* According to the MSDN docs we
461 * should adjust values between 1 and
462 * 499 to 500, but the MS runtime
469 SocketOptionLevel.Socket,
470 SocketOptionName.SendTimeout, value);
474 public int ReceiveTimeout {
476 if (disposed && closed)
477 throw new ObjectDisposedException (GetType ().ToString ());
479 return (int)GetSocketOption(
480 SocketOptionLevel.Socket,
481 SocketOptionName.ReceiveTimeout);
484 if (disposed && closed)
485 throw new ObjectDisposedException (GetType ().ToString ());
488 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
495 SocketOptionLevel.Socket,
496 SocketOptionName.ReceiveTimeout, value);
500 public bool AcceptAsync (SocketAsyncEventArgs e)
502 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
504 if (disposed && closed)
505 throw new ObjectDisposedException (GetType ().ToString ());
507 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
509 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
510 if (e.BufferList != null)
511 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
513 throw new ArgumentOutOfRangeException ("e.Count");
515 Socket acceptSocket = e.AcceptSocket;
516 if (acceptSocket != null) {
517 if (acceptSocket.IsBound || acceptSocket.Connected)
518 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
523 w.Init (this, e, SocketOperation.Accept);
526 readQ.Enqueue (e.Worker);
530 socket_pool_queue (Worker.Dispatcher, w.result);
533 // Creates a new system socket, returning the handle
534 [MethodImplAttribute(MethodImplOptions.InternalCall)]
535 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
537 public Socket Accept() {
538 if (disposed && closed)
539 throw new ObjectDisposedException (GetType ().ToString ());
542 IntPtr sock = (IntPtr) (-1);
544 RegisterForBlockingSyscall ();
545 sock = Accept_internal(socket, out error, blocking);
547 UnRegisterForBlockingSyscall ();
552 error = SOCKET_CLOSED;
553 throw new SocketException(error);
556 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
557 this.ProtocolType, sock);
559 accepted.seed_endpoint = this.seed_endpoint;
560 accepted.Blocking = this.Blocking;
564 internal void Accept (Socket acceptSocket)
566 if (disposed && closed)
567 throw new ObjectDisposedException (GetType ().ToString ());
570 IntPtr sock = (IntPtr)(-1);
573 RegisterForBlockingSyscall ();
574 sock = Accept_internal (socket, out error, blocking);
576 UnRegisterForBlockingSyscall ();
581 error = SOCKET_CLOSED;
582 throw new SocketException (error);
585 acceptSocket.address_family = this.AddressFamily;
586 acceptSocket.socket_type = this.SocketType;
587 acceptSocket.protocol_type = this.ProtocolType;
588 acceptSocket.socket = sock;
589 acceptSocket.connected = true;
590 acceptSocket.seed_endpoint = this.seed_endpoint;
591 acceptSocket.Blocking = this.Blocking;
593 /* FIXME: figure out what if anything else
598 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
600 if (disposed && closed)
601 throw new ObjectDisposedException (GetType ().ToString ());
603 if (!isbound || !islistening)
604 throw new InvalidOperationException ();
606 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
609 readQ.Enqueue (req.Worker);
613 socket_pool_queue (Worker.Dispatcher, req);
617 public IAsyncResult BeginAccept (int receiveSize,
618 AsyncCallback callback,
621 if (disposed && closed)
622 throw new ObjectDisposedException (GetType ().ToString ());
625 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
627 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
628 req.Buffer = new byte[receiveSize];
630 req.Size = receiveSize;
631 req.SockFlags = SocketFlags.None;
634 readQ.Enqueue (req.Worker);
638 socket_pool_queue (Worker.Dispatcher, req);
642 public IAsyncResult BeginAccept (Socket acceptSocket,
644 AsyncCallback callback,
647 if (disposed && closed)
648 throw new ObjectDisposedException (GetType ().ToString ());
651 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
653 if (acceptSocket != null) {
654 if (acceptSocket.disposed && acceptSocket.closed)
655 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
657 if (acceptSocket.IsBound)
658 throw new InvalidOperationException ();
660 /* For some reason the MS runtime
661 * barfs if the new socket is not TCP,
662 * even though it's just about to blow
663 * away all those parameters
665 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
666 throw new SocketException ((int)SocketError.InvalidArgument);
669 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
670 req.Buffer = new byte[receiveSize];
672 req.Size = receiveSize;
673 req.SockFlags = SocketFlags.None;
674 req.AcceptSocket = acceptSocket;
677 readQ.Enqueue (req.Worker);
681 socket_pool_queue (Worker.Dispatcher, req);
685 public IAsyncResult BeginConnect (IPAddress address, int port,
686 AsyncCallback callback,
689 if (disposed && closed)
690 throw new ObjectDisposedException (GetType ().ToString ());
693 throw new ArgumentNullException ("address");
695 if (address.ToString ().Length == 0)
696 throw new ArgumentException ("The length of the IP address is zero");
698 if (port <= 0 || port > 65535)
699 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
702 throw new InvalidOperationException ();
704 IPEndPoint iep = new IPEndPoint (address, port);
705 return(BeginConnect (iep, callback, state));
708 public IAsyncResult BeginConnect (string host, int port,
709 AsyncCallback callback,
712 if (disposed && closed)
713 throw new ObjectDisposedException (GetType ().ToString ());
716 throw new ArgumentNullException ("host");
718 if (address_family != AddressFamily.InterNetwork &&
719 address_family != AddressFamily.InterNetworkV6)
720 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
722 if (port <= 0 || port > 65535)
723 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
726 throw new InvalidOperationException ();
728 return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
731 public IAsyncResult BeginDisconnect (bool reuseSocket,
732 AsyncCallback callback,
735 if (disposed && closed)
736 throw new ObjectDisposedException (GetType ().ToString ());
738 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
739 req.ReuseSocket = reuseSocket;
740 socket_pool_queue (Worker.Dispatcher, req);
744 void CheckRange (byte[] buffer, int offset, int size)
747 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
749 if (offset > buffer.Length)
750 throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
753 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
755 if (size > buffer.Length - offset)
756 throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
759 public IAsyncResult BeginReceive(byte[] buffer, int offset,
761 SocketFlags socket_flags,
762 AsyncCallback callback,
765 if (disposed && closed)
766 throw new ObjectDisposedException (GetType ().ToString ());
769 throw new ArgumentNullException ("buffer");
771 CheckRange (buffer, offset, size);
773 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
777 req.SockFlags = socket_flags;
780 readQ.Enqueue (req.Worker);
784 socket_pool_queue (Worker.Dispatcher, req);
788 public IAsyncResult BeginReceive (byte[] buffer, int offset,
789 int size, SocketFlags flags,
790 out SocketError error,
791 AsyncCallback callback,
794 /* As far as I can tell from the docs and from
795 * experimentation, a pointer to the
796 * SocketError parameter is not supposed to be
797 * saved for the async parts. And as we don't
798 * set any socket errors in the setup code, we
799 * just have to set it to Success.
801 error = SocketError.Success;
802 return (BeginReceive (buffer, offset, size, flags, callback, state));
805 [CLSCompliant (false)]
806 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
807 SocketFlags socketFlags,
808 AsyncCallback callback,
811 if (disposed && closed)
812 throw new ObjectDisposedException (GetType ().ToString ());
815 throw new ArgumentNullException ("buffers");
817 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
818 req.Buffers = buffers;
819 req.SockFlags = socketFlags;
822 readQ.Enqueue (req.Worker);
826 socket_pool_queue (Worker.Dispatcher, req);
830 [CLSCompliant (false)]
831 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
832 SocketFlags socketFlags,
833 out SocketError errorCode,
834 AsyncCallback callback,
837 /* I assume the same SocketError semantics as
840 errorCode = SocketError.Success;
841 return (BeginReceive (buffers, socketFlags, callback, state));
844 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
846 SocketFlags socket_flags,
847 ref EndPoint remote_end,
848 AsyncCallback callback,
850 if (disposed && closed)
851 throw new ObjectDisposedException (GetType ().ToString ());
854 throw new ArgumentNullException ("buffer");
856 if (remote_end == null)
857 throw new ArgumentNullException ("remote_end");
859 CheckRange (buffer, offset, size);
861 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
865 req.SockFlags = socket_flags;
866 req.EndPoint = remote_end;
869 readQ.Enqueue (req.Worker);
873 socket_pool_queue (Worker.Dispatcher, req);
878 public IAsyncResult BeginReceiveMessageFrom (
879 byte[] buffer, int offset, int size,
880 SocketFlags socketFlags, ref EndPoint remoteEP,
881 AsyncCallback callback, object state)
883 if (disposed && closed)
884 throw new ObjectDisposedException (GetType ().ToString ());
887 throw new ArgumentNullException ("buffer");
889 if (remoteEP == null)
890 throw new ArgumentNullException ("remoteEP");
892 CheckRange (buffer, offset, size);
894 throw new NotImplementedException ();
897 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
898 AsyncCallback callback, object state)
900 if (disposed && closed)
901 throw new ObjectDisposedException (GetType ().ToString ());
904 throw new ArgumentNullException ("buffer");
906 CheckRange (buffer, offset, size);
909 throw new SocketException ((int)SocketError.NotConnected);
911 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
915 req.SockFlags = socket_flags;
918 writeQ.Enqueue (req.Worker);
919 count = writeQ.Count;
922 socket_pool_queue (Worker.Dispatcher, req);
926 public IAsyncResult BeginSend (byte[] buffer, int offset,
928 SocketFlags socketFlags,
929 out SocketError errorCode,
930 AsyncCallback callback,
934 errorCode = SocketError.NotConnected;
935 throw new SocketException ((int)errorCode);
938 errorCode = SocketError.Success;
940 return (BeginSend (buffer, offset, size, socketFlags, callback,
944 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
945 SocketFlags socketFlags,
946 AsyncCallback callback,
949 if (disposed && closed)
950 throw new ObjectDisposedException (GetType ().ToString ());
953 throw new ArgumentNullException ("buffers");
956 throw new SocketException ((int)SocketError.NotConnected);
958 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
959 req.Buffers = buffers;
960 req.SockFlags = socketFlags;
963 writeQ.Enqueue (req.Worker);
964 count = writeQ.Count;
967 socket_pool_queue (Worker.Dispatcher, req);
971 [CLSCompliant (false)]
972 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
973 SocketFlags socketFlags,
974 out SocketError errorCode,
975 AsyncCallback callback,
979 errorCode = SocketError.NotConnected;
980 throw new SocketException ((int)errorCode);
983 errorCode = SocketError.Success;
984 return (BeginSend (buffers, socketFlags, callback, state));
987 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
989 sealed class SendFileAsyncResult : IAsyncResult {
993 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
999 public object AsyncState {
1000 get { return ares.AsyncState; }
1003 public WaitHandle AsyncWaitHandle {
1004 get { return ares.AsyncWaitHandle; }
1007 public bool CompletedSynchronously {
1008 get { return ares.CompletedSynchronously; }
1011 public bool IsCompleted {
1012 get { return ares.IsCompleted; }
1015 public SendFileHandler Delegate {
1019 public IAsyncResult Original {
1020 get { return ares; }
1024 public IAsyncResult BeginSendFile (string fileName,
1025 AsyncCallback callback,
1028 if (disposed && closed)
1029 throw new ObjectDisposedException (GetType ().ToString ());
1032 throw new NotSupportedException ();
1034 if (!File.Exists (fileName))
1035 throw new FileNotFoundException ();
1037 return BeginSendFile (fileName, null, null, 0, callback, state);
1040 public IAsyncResult BeginSendFile (string fileName,
1043 TransmitFileOptions flags,
1044 AsyncCallback callback,
1047 if (disposed && closed)
1048 throw new ObjectDisposedException (GetType ().ToString ());
1051 throw new NotSupportedException ();
1053 if (!File.Exists (fileName))
1054 throw new FileNotFoundException ();
1056 SendFileHandler d = new SendFileHandler (SendFile);
1057 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, ar => {
1058 SendFileAsyncResult sfar = new SendFileAsyncResult (d, ar);
1063 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1065 SocketFlags socket_flags,
1066 EndPoint remote_end,
1067 AsyncCallback callback,
1069 if (disposed && closed)
1070 throw new ObjectDisposedException (GetType ().ToString ());
1073 throw new ArgumentNullException ("buffer");
1075 CheckRange (buffer, offset, size);
1077 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1078 req.Buffer = buffer;
1079 req.Offset = offset;
1081 req.SockFlags = socket_flags;
1082 req.EndPoint = remote_end;
1085 writeQ.Enqueue (req.Worker);
1086 count = writeQ.Count;
1089 socket_pool_queue (Worker.Dispatcher, req);
1093 // Creates a new system socket, returning the handle
1094 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1095 private extern static void Bind_internal(IntPtr sock,
1099 public void Bind(EndPoint local_end) {
1100 if (disposed && closed)
1101 throw new ObjectDisposedException (GetType ().ToString ());
1103 if (local_end == null)
1104 throw new ArgumentNullException("local_end");
1108 Bind_internal(socket, local_end.Serialize(), out error);
1110 throw new SocketException (error);
1114 seed_endpoint = local_end;
1117 public void Connect (IPAddress address, int port)
1119 Connect (new IPEndPoint (address, port));
1122 public void Connect (IPAddress[] addresses, int port)
1124 if (disposed && closed)
1125 throw new ObjectDisposedException (GetType ().ToString ());
1127 if (addresses == null)
1128 throw new ArgumentNullException ("addresses");
1130 if (this.AddressFamily != AddressFamily.InterNetwork &&
1131 this.AddressFamily != AddressFamily.InterNetworkV6)
1132 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1135 throw new InvalidOperationException ();
1137 /* FIXME: do non-blocking sockets Poll here? */
1139 foreach (IPAddress address in addresses) {
1140 IPEndPoint iep = new IPEndPoint (address, port);
1141 SocketAddress serial = iep.Serialize ();
1143 Connect_internal (socket, serial, out error);
1147 seed_endpoint = iep;
1149 } else if (error != (int)SocketError.InProgress &&
1150 error != (int)SocketError.WouldBlock) {
1155 Poll (-1, SelectMode.SelectWrite);
1156 error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1160 seed_endpoint = iep;
1166 throw new SocketException (error);
1169 public void Connect (string host, int port)
1171 IPAddress [] addresses = Dns.GetHostAddresses (host);
1172 Connect (addresses, port);
1175 public bool DisconnectAsync (SocketAsyncEventArgs e)
1177 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1178 if (disposed && closed)
1179 throw new ObjectDisposedException (GetType ().ToString ());
1182 e.Worker.Init (this, e, SocketOperation.Disconnect);
1183 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();
1296 public void EndDisconnect (IAsyncResult asyncResult)
1298 if (disposed && closed)
1299 throw new ObjectDisposedException (GetType ().ToString ());
1301 if (asyncResult == null)
1302 throw new ArgumentNullException ("asyncResult");
1304 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1306 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1308 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1309 throw InvalidAsyncOp ("EndDisconnect");
1310 if (!asyncResult.IsCompleted)
1311 asyncResult.AsyncWaitHandle.WaitOne ();
1313 req.CheckIfThrowDelayedException ();
1317 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
1318 ref SocketFlags socketFlags,
1319 ref EndPoint endPoint,
1320 out IPPacketInformation ipPacketInformation)
1322 if (disposed && closed)
1323 throw new ObjectDisposedException (GetType ().ToString ());
1325 if (asyncResult == null)
1326 throw new ArgumentNullException ("asyncResult");
1328 if (endPoint == null)
1329 throw new ArgumentNullException ("endPoint");
1331 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1333 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1335 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1336 throw InvalidAsyncOp ("EndReceiveMessageFrom");
1337 throw new NotImplementedException ();
1340 public void EndSendFile (IAsyncResult asyncResult)
1342 if (disposed && closed)
1343 throw new ObjectDisposedException (GetType ().ToString ());
1345 if (asyncResult == null)
1346 throw new ArgumentNullException ("asyncResult");
1348 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
1350 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1352 ares.Delegate.EndInvoke (ares.Original);
1355 public int EndSendTo (IAsyncResult result)
1357 if (disposed && closed)
1358 throw new ObjectDisposedException (GetType ().ToString ());
1361 throw new ArgumentNullException ("result");
1363 SocketAsyncResult req = result as SocketAsyncResult;
1365 throw new ArgumentException ("Invalid IAsyncResult", "result");
1367 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1368 throw InvalidAsyncOp ("EndSendTo");
1369 if (!result.IsCompleted)
1370 result.AsyncWaitHandle.WaitOne();
1372 req.CheckIfThrowDelayedException();
1376 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1377 private extern static void GetSocketOption_arr_internal(IntPtr socket,
1378 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
1381 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
1383 if (disposed && closed)
1384 throw new ObjectDisposedException (GetType ().ToString ());
1386 if (optionValue == null)
1387 throw new SocketException ((int) SocketError.Fault,
1388 "Error trying to dereference an invalid pointer");
1392 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
1395 throw new SocketException (error);
1398 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
1400 if (disposed && closed)
1401 throw new ObjectDisposedException (GetType ().ToString ());
1403 byte[] byte_val=new byte[length];
1406 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
1409 throw new SocketException (error);
1414 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1415 // common options between UNIX and Winsock are FIONREAD,
1416 // FIONBIO and SIOCATMARK. Anything else will depend on the
1417 // system except SIO_KEEPALIVE_VALS which is properly handled
1418 // on both windows and linux.
1419 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1420 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
1421 byte [] output, out int error);
1423 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1426 throw new ObjectDisposedException (GetType ().ToString ());
1429 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
1433 throw new SocketException (error);
1436 throw new InvalidOperationException ("Must use Blocking property instead.");
1441 public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
1443 return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
1446 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1447 private extern static void Listen_internal(IntPtr sock, int backlog, out int error);
1449 public void Listen (int backlog)
1451 if (disposed && closed)
1452 throw new ObjectDisposedException (GetType ().ToString ());
1455 throw new SocketException ((int)SocketError.InvalidArgument);
1458 Listen_internal(socket, backlog, out error);
1461 throw new SocketException (error);
1466 public bool Poll (int time_us, SelectMode mode)
1468 if (disposed && closed)
1469 throw new ObjectDisposedException (GetType ().ToString ());
1471 if (mode != SelectMode.SelectRead &&
1472 mode != SelectMode.SelectWrite &&
1473 mode != SelectMode.SelectError)
1474 throw new NotSupportedException ("'mode' parameter is not valid.");
1477 bool result = Poll_internal (socket, mode, time_us, out error);
1479 throw new SocketException (error);
1481 if (mode == SelectMode.SelectWrite && result && !connected) {
1482 /* Update the connected state; for
1483 * non-blocking Connect()s this is
1484 * when we can find out that the
1485 * connect succeeded.
1487 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
1495 public int Receive (byte [] buffer)
1497 if (disposed && closed)
1498 throw new ObjectDisposedException (GetType ().ToString ());
1501 throw new ArgumentNullException ("buffer");
1505 int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
1507 if (error != SocketError.Success)
1508 throw new SocketException ((int) error);
1513 public int Receive (byte [] buffer, SocketFlags flags)
1515 if (disposed && closed)
1516 throw new ObjectDisposedException (GetType ().ToString ());
1519 throw new ArgumentNullException ("buffer");
1523 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
1525 if (error != SocketError.Success) {
1526 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1527 throw new SocketException ((int) error, "Operation timed out.");
1528 throw new SocketException ((int) error);
1534 public int Receive (byte [] buffer, int size, SocketFlags flags)
1536 if (disposed && closed)
1537 throw new ObjectDisposedException (GetType ().ToString ());
1540 throw new ArgumentNullException ("buffer");
1542 CheckRange (buffer, 0, size);
1546 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
1548 if (error != SocketError.Success) {
1549 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1550 throw new SocketException ((int) error, "Operation timed out.");
1551 throw new SocketException ((int) error);
1557 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
1559 if (disposed && closed)
1560 throw new ObjectDisposedException (GetType ().ToString ());
1563 throw new ArgumentNullException ("buffer");
1565 CheckRange (buffer, offset, size);
1569 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
1571 if (error != SocketError.Success) {
1572 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1573 throw new SocketException ((int) error, "Operation timed out.");
1574 throw new SocketException ((int) error);
1580 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
1582 if (disposed && closed)
1583 throw new ObjectDisposedException (GetType ().ToString ());
1586 throw new ArgumentNullException ("buffer");
1588 CheckRange (buffer, offset, size);
1590 return Receive_nochecks (buffer, offset, size, flags, out error);
1593 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
1595 if (disposed && closed)
1596 throw new ObjectDisposedException (GetType ().ToString ());
1598 // We do not support recv into multiple buffers yet
1599 if (e.BufferList != null)
1600 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1601 if (e.RemoteEndPoint == null)
1602 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1605 e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
1606 SocketAsyncResult res = e.Worker.result;
1607 res.Buffer = e.Buffer;
1608 res.Offset = e.Offset;
1610 res.EndPoint = e.RemoteEndPoint;
1611 res.SockFlags = e.SocketFlags;
1614 readQ.Enqueue (e.Worker);
1615 count = readQ.Count;
1618 socket_pool_queue (Worker.Dispatcher, res);
1622 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
1624 if (disposed && closed)
1625 throw new ObjectDisposedException (GetType ().ToString ());
1628 throw new ArgumentNullException ("buffer");
1630 if (remoteEP == null)
1631 throw new ArgumentNullException ("remoteEP");
1633 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
1636 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
1638 if (disposed && closed)
1639 throw new ObjectDisposedException (GetType ().ToString ());
1642 throw new ArgumentNullException ("buffer");
1644 if (remoteEP == null)
1645 throw new ArgumentNullException ("remoteEP");
1647 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
1650 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
1651 ref EndPoint remoteEP)
1653 if (disposed && closed)
1654 throw new ObjectDisposedException (GetType ().ToString ());
1657 throw new ArgumentNullException ("buffer");
1659 if (remoteEP == null)
1660 throw new ArgumentNullException ("remoteEP");
1662 if (size < 0 || size > buffer.Length)
1663 throw new ArgumentOutOfRangeException ("size");
1665 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
1668 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1669 private extern static int RecvFrom_internal(IntPtr sock,
1674 ref SocketAddress sockaddr,
1677 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
1678 ref EndPoint remoteEP)
1680 if (disposed && closed)
1681 throw new ObjectDisposedException (GetType ().ToString ());
1684 throw new ArgumentNullException ("buffer");
1686 if (remoteEP == null)
1687 throw new ArgumentNullException ("remoteEP");
1689 CheckRange (buffer, offset, size);
1691 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
1694 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1695 ref EndPoint remote_end)
1698 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
1701 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
1702 ref EndPoint remote_end, bool throwOnError, out int error)
1704 SocketAddress sockaddr = remote_end.Serialize();
1705 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1706 SocketError err = (SocketError) error;
1708 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
1710 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
1712 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
1713 error = (int) SocketError.TimedOut;
1718 throw new SocketException (error);
1725 // If sockaddr is null then we're a connection
1726 // oriented protocol and should ignore the
1727 // remote_end parameter (see MSDN
1728 // documentation for Socket.ReceiveFrom(...) )
1730 if ( sockaddr != null ) {
1731 // Stupidly, EndPoint.Create() is an
1733 remote_end = remote_end.Create (sockaddr);
1736 seed_endpoint = remote_end;
1741 [MonoTODO ("Not implemented")]
1742 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
1744 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1745 if (disposed && closed)
1746 throw new ObjectDisposedException (GetType ().ToString ());
1748 throw new NotImplementedException ();
1751 [MonoTODO ("Not implemented")]
1752 public int ReceiveMessageFrom (byte[] buffer, int offset,
1754 ref SocketFlags socketFlags,
1755 ref EndPoint remoteEP,
1756 out IPPacketInformation ipPacketInformation)
1758 if (disposed && closed)
1759 throw new ObjectDisposedException (GetType ().ToString ());
1762 throw new ArgumentNullException ("buffer");
1764 if (remoteEP == null)
1765 throw new ArgumentNullException ("remoteEP");
1767 CheckRange (buffer, offset, size);
1769 /* FIXME: figure out how we get hold of the
1770 * IPPacketInformation
1772 throw new NotImplementedException ();
1775 [MonoTODO ("Not implemented")]
1776 public bool SendPacketsAsync (SocketAsyncEventArgs e)
1778 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1780 if (disposed && closed)
1781 throw new ObjectDisposedException (GetType ().ToString ());
1783 throw new NotImplementedException ();
1786 public int Send (byte [] buf)
1788 if (disposed && closed)
1789 throw new ObjectDisposedException (GetType ().ToString ());
1792 throw new ArgumentNullException ("buf");
1796 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
1798 if (error != SocketError.Success)
1799 throw new SocketException ((int) error);
1804 public int Send (byte [] buf, SocketFlags flags)
1806 if (disposed && closed)
1807 throw new ObjectDisposedException (GetType ().ToString ());
1810 throw new ArgumentNullException ("buf");
1814 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
1816 if (error != SocketError.Success)
1817 throw new SocketException ((int) error);
1822 public int Send (byte [] buf, int size, SocketFlags flags)
1824 if (disposed && closed)
1825 throw new ObjectDisposedException (GetType ().ToString ());
1828 throw new ArgumentNullException ("buf");
1830 CheckRange (buf, 0, size);
1834 int ret = Send_nochecks (buf, 0, size, flags, out error);
1836 if (error != SocketError.Success)
1837 throw new SocketException ((int) error);
1842 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
1844 if (disposed && closed)
1845 throw new ObjectDisposedException (GetType ().ToString ());
1848 throw new ArgumentNullException ("buffer");
1850 CheckRange (buf, offset, size);
1854 int ret = Send_nochecks (buf, offset, size, flags, out error);
1856 if (error != SocketError.Success)
1857 throw new SocketException ((int) error);
1862 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
1864 if (disposed && closed)
1865 throw new ObjectDisposedException (GetType ().ToString ());
1868 throw new ArgumentNullException ("buffer");
1870 CheckRange (buf, offset, size);
1872 return Send_nochecks (buf, offset, size, flags, out error);
1875 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1876 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
1878 public void SendFile (string fileName)
1880 if (disposed && closed)
1881 throw new ObjectDisposedException (GetType ().ToString ());
1884 throw new NotSupportedException ();
1887 throw new InvalidOperationException ();
1889 SendFile (fileName, null, null, 0);
1892 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
1894 if (disposed && closed)
1895 throw new ObjectDisposedException (GetType ().ToString ());
1898 throw new NotSupportedException ();
1901 throw new InvalidOperationException ();
1903 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
1904 SocketException exc = new SocketException ();
1905 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
1906 throw new FileNotFoundException ();
1911 public bool SendToAsync (SocketAsyncEventArgs e)
1913 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1915 if (disposed && closed)
1916 throw new ObjectDisposedException (GetType ().ToString ());
1917 if (e.BufferList != null)
1918 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1919 if (e.RemoteEndPoint == null)
1920 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1923 e.Worker.Init (this, e, SocketOperation.SendTo);
1924 SocketAsyncResult res = e.Worker.result;
1925 res.Buffer = e.Buffer;
1926 res.Offset = e.Offset;
1928 res.SockFlags = e.SocketFlags;
1929 res.EndPoint = e.RemoteEndPoint;
1932 writeQ.Enqueue (e.Worker);
1933 count = writeQ.Count;
1936 socket_pool_queue (Worker.Dispatcher, res);
1940 public int SendTo (byte [] buffer, EndPoint remote_end)
1942 if (disposed && closed)
1943 throw new ObjectDisposedException (GetType ().ToString ());
1946 throw new ArgumentNullException ("buffer");
1948 if (remote_end == null)
1949 throw new ArgumentNullException ("remote_end");
1951 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
1954 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
1956 if (disposed && closed)
1957 throw new ObjectDisposedException (GetType ().ToString ());
1960 throw new ArgumentNullException ("buffer");
1962 if (remote_end == null)
1963 throw new ArgumentNullException ("remote_end");
1965 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
1968 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
1970 if (disposed && closed)
1971 throw new ObjectDisposedException (GetType ().ToString ());
1974 throw new ArgumentNullException ("buffer");
1976 if (remote_end == null)
1977 throw new ArgumentNullException ("remote_end");
1979 CheckRange (buffer, 0, size);
1981 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
1984 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1985 private extern static int SendTo_internal(IntPtr sock,
1993 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
1994 EndPoint remote_end)
1996 if (disposed && closed)
1997 throw new ObjectDisposedException (GetType ().ToString ());
2000 throw new ArgumentNullException ("buffer");
2002 if (remote_end == null)
2003 throw new ArgumentNullException("remote_end");
2005 CheckRange (buffer, offset, size);
2007 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2010 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2011 EndPoint remote_end)
2013 SocketAddress sockaddr = remote_end.Serialize ();
2017 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2019 SocketError err = (SocketError) error;
2021 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2024 throw new SocketException (error);
2029 seed_endpoint = remote_end;
2034 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2036 if (disposed && closed)
2037 throw new ObjectDisposedException (GetType ().ToString ());
2039 // I'd throw an ArgumentNullException, but this is what MS does.
2040 if (optionValue == null)
2041 throw new SocketException ((int) SocketError.Fault,
2042 "Error trying to dereference an invalid pointer");
2046 SetSocketOption_internal (socket, optionLevel, optionName, null,
2047 optionValue, 0, out error);
2050 if (error == (int) SocketError.InvalidArgument)
2051 throw new ArgumentException ();
2052 throw new SocketException (error);
2056 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
2058 if (disposed && closed)
2059 throw new ObjectDisposedException (GetType ().ToString ());
2061 // NOTE: if a null is passed, the byte[] overload is used instead...
2062 if (optionValue == null)
2063 throw new ArgumentNullException("optionValue");
2067 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
2068 LingerOption linger = optionValue as LingerOption;
2070 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
2071 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
2072 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2073 MulticastOption multicast = optionValue as MulticastOption;
2074 if (multicast == null)
2075 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
2076 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2077 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2078 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
2079 if (multicast == null)
2080 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
2081 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2083 throw new ArgumentException ("Invalid value specified.", "optionValue");
2087 if (error == (int) SocketError.InvalidArgument)
2088 throw new ArgumentException ();
2089 throw new SocketException (error);
2093 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
2095 if (disposed && closed)
2096 throw new ObjectDisposedException (GetType ().ToString ());
2099 int int_val = (optionValue) ? 1 : 0;
2100 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
2102 if (error == (int) SocketError.InvalidArgument)
2103 throw new ArgumentException ();
2104 throw new SocketException (error);