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;
58 private const int SOCKET_CLOSED = 10004;
60 static void AddSockets (List<Socket> sockets, IList list, string name)
63 foreach (Socket sock in list) {
64 if (sock == null) // MS throws a NullRef
65 throw new ArgumentNullException ("name", "Contains a null element");
73 [MethodImplAttribute(MethodImplOptions.InternalCall)]
74 private extern static void Select_internal (ref Socket [] sockets,
78 public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
80 var list = new List<Socket> ();
81 AddSockets (list, checkRead, "checkRead");
82 AddSockets (list, checkWrite, "checkWrite");
83 AddSockets (list, checkError, "checkError");
85 if (list.Count == 3) {
86 throw new ArgumentNullException ("checkRead, checkWrite, checkError",
87 "All the lists are null or empty.");
92 * The 'sockets' array contains: READ socket 0-n, null,
93 * WRITE socket 0-n, null,
94 * ERROR socket 0-n, null
96 Socket [] sockets = list.ToArray ();
97 Select_internal (ref sockets, microSeconds, out error);
100 throw new SocketException (error);
102 if (sockets == null) {
103 if (checkRead != null)
105 if (checkWrite != null)
107 if (checkError != null)
113 int count = sockets.Length;
114 IList currentList = checkRead;
116 for (int i = 0; i < count; i++) {
117 Socket sock = sockets [i];
118 if (sock == null) { // separator
119 if (currentList != null) {
120 // Remove non-signaled sockets after the current one
121 int to_remove = currentList.Count - currentIdx;
122 for (int k = 0; k < to_remove; k++)
123 currentList.RemoveAt (currentIdx);
125 currentList = (mode == 0) ? checkWrite : checkError;
131 if (mode == 1 && currentList == checkWrite && !sock.connected) {
132 if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
133 sock.connected = true;
136 // Remove non-signaled sockets before the current one
137 //int max = currentList.Count;
138 while (((Socket) currentList [currentIdx]) != sock) {
139 currentList.RemoveAt (currentIdx);
145 // private constructor used by Accept, which already
146 // has a socket handle to use
147 internal Socket(AddressFamily family, SocketType type,
148 ProtocolType proto, IntPtr sock)
150 address_family=family;
158 private void SocketDefaults ()
161 if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
162 address_family == AddressFamily.InterNetworkV6 */) {
163 /* This is the default, but it
164 * probably has nasty side
165 * effects on Linux, as the
166 * socket option is kludged by
167 * turning on or off PMTU
170 this.DontFragment = false;
174 // Microsoft sets these to 8192, but we are going to keep them
175 // both to the OS defaults as these have a big performance impact.
176 // on WebClient performance.
178 //this.ReceiveBufferSize = 8192;
179 //this.SendBufferSize = 8192;
180 } catch (SocketException) {
185 public Socket (SocketInformation socketInformation)
187 var options = socketInformation.Options;
188 islistening = (options & SocketInformationOptions.Listening) != 0;
189 connected = (options & SocketInformationOptions.Connected) != 0;
190 blocking = (options & SocketInformationOptions.NonBlocking) == 0;
191 useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
193 var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
195 address_family = (AddressFamily) (int) result [0];
196 socket_type = (SocketType) (int) result [1];
197 protocol_type = (ProtocolType) (int) result [2];
198 isbound = (ProtocolType) (int) result [3] != 0;
199 socket = (IntPtr) (long) result [4];
205 // Returns the amount of data waiting to be read on socket
206 [MethodImplAttribute(MethodImplOptions.InternalCall)]
207 private extern static int Available_internal(IntPtr socket, out int error);
210 public int Available {
212 if (disposed && closed)
213 throw new ObjectDisposedException (GetType ().ToString ());
217 ret = Available_internal(socket, out error);
220 throw new SocketException (error);
227 public bool DontFragment {
229 if (disposed && closed) {
230 throw new ObjectDisposedException (GetType ().ToString ());
235 if (address_family == AddressFamily.InterNetwork) {
236 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
237 } else if (address_family == AddressFamily.InterNetworkV6) {
238 dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
240 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
243 return(dontfragment);
246 if (disposed && closed) {
247 throw new ObjectDisposedException (GetType ().ToString ());
250 if (address_family == AddressFamily.InterNetwork) {
251 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
252 } else if (address_family == AddressFamily.InterNetworkV6) {
253 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
255 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
260 public bool EnableBroadcast {
262 if (disposed && closed) {
263 throw new ObjectDisposedException (GetType ().ToString ());
266 if (protocol_type != ProtocolType.Udp) {
267 throw new SocketException ((int)SocketError.ProtocolOption);
270 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
273 if (disposed && closed) {
274 throw new ObjectDisposedException (GetType ().ToString ());
277 if (protocol_type != ProtocolType.Udp) {
278 throw new SocketException ((int)SocketError.ProtocolOption);
281 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
285 public bool ExclusiveAddressUse {
287 if (disposed && closed) {
288 throw new ObjectDisposedException (GetType ().ToString ());
291 return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
294 if (disposed && closed) {
295 throw new ObjectDisposedException (GetType ().ToString ());
298 throw new InvalidOperationException ("Bind has already been called for this socket");
301 SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
305 public bool IsBound {
311 public LingerOption LingerState {
313 if (disposed && closed) {
314 throw new ObjectDisposedException (GetType ().ToString ());
317 return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
320 if (disposed && closed) {
321 throw new ObjectDisposedException (GetType ().ToString ());
324 SetSocketOption (SocketOptionLevel.Socket,
325 SocketOptionName.Linger,
330 public bool MulticastLoopback {
332 if (disposed && closed) {
333 throw new ObjectDisposedException (GetType ().ToString ());
336 /* Even though this option can be set
337 * for TCP sockets on Linux, throw
338 * this exception anyway to be
339 * compatible (the MSDN docs say
340 * "Setting this property on a
341 * Transmission Control Protocol (TCP)
342 * socket will have no effect." but
343 * the MS runtime throws the
346 if (protocol_type == ProtocolType.Tcp) {
347 throw new SocketException ((int)SocketError.ProtocolOption);
350 bool multicastloopback;
352 if (address_family == AddressFamily.InterNetwork) {
353 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
354 } else if (address_family == AddressFamily.InterNetworkV6) {
355 multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
357 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
360 return(multicastloopback);
363 if (disposed && closed) {
364 throw new ObjectDisposedException (GetType ().ToString ());
367 /* Even though this option can be set
368 * for TCP sockets on Linux, throw
369 * this exception anyway to be
370 * compatible (the MSDN docs say
371 * "Setting this property on a
372 * Transmission Control Protocol (TCP)
373 * socket will have no effect." but
374 * the MS runtime throws the
377 if (protocol_type == ProtocolType.Tcp) {
378 throw new SocketException ((int)SocketError.ProtocolOption);
381 if (address_family == AddressFamily.InterNetwork) {
382 SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
383 } else if (address_family == AddressFamily.InterNetworkV6) {
384 SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
386 throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
392 [MonoTODO ("This doesn't do anything on Mono yet")]
393 public bool UseOnlyOverlappedIO {
395 return(useoverlappedIO);
398 useoverlappedIO = value;
402 public IntPtr Handle {
409 // Returns the local endpoint details in addr and port
410 [MethodImplAttribute(MethodImplOptions.InternalCall)]
411 private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
414 // Wish: support non-IP endpoints.
415 public EndPoint LocalEndPoint {
417 if (disposed && closed)
418 throw new ObjectDisposedException (GetType ().ToString ());
421 * If the seed EndPoint is null, Connect, Bind,
422 * etc has not yet been called. MS returns null
425 if (seed_endpoint == null)
431 sa=LocalEndPoint_internal(socket, (int) address_family, out error);
434 throw new SocketException (error);
436 return seed_endpoint.Create (sa);
440 public SocketType SocketType {
446 public int SendTimeout {
448 if (disposed && closed)
449 throw new ObjectDisposedException (GetType ().ToString ());
451 return (int)GetSocketOption(
452 SocketOptionLevel.Socket,
453 SocketOptionName.SendTimeout);
456 if (disposed && closed)
457 throw new ObjectDisposedException (GetType ().ToString ());
460 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
462 /* According to the MSDN docs we
463 * should adjust values between 1 and
464 * 499 to 500, but the MS runtime
471 SocketOptionLevel.Socket,
472 SocketOptionName.SendTimeout, value);
476 public int ReceiveTimeout {
478 if (disposed && closed)
479 throw new ObjectDisposedException (GetType ().ToString ());
481 return (int)GetSocketOption(
482 SocketOptionLevel.Socket,
483 SocketOptionName.ReceiveTimeout);
486 if (disposed && closed)
487 throw new ObjectDisposedException (GetType ().ToString ());
490 throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
497 SocketOptionLevel.Socket,
498 SocketOptionName.ReceiveTimeout, value);
503 public bool AcceptAsync (SocketAsyncEventArgs e)
505 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
507 if (disposed && closed)
508 throw new ObjectDisposedException (GetType ().ToString ());
510 throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
512 throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
513 if (e.BufferList != null)
514 throw new ArgumentException ("Multiple buffers cannot be used with this method.");
516 throw new ArgumentOutOfRangeException ("e.Count");
518 Socket acceptSocket = e.AcceptSocket;
519 if (acceptSocket != null) {
520 if (acceptSocket.IsBound || acceptSocket.Connected)
521 throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
526 w.Init (this, e, SocketOperation.Accept);
529 readQ.Enqueue (e.Worker);
533 socket_pool_queue (Worker.Dispatcher, w.result);
537 // Creates a new system socket, returning the handle
538 [MethodImplAttribute(MethodImplOptions.InternalCall)]
539 private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
541 public Socket Accept() {
542 if (disposed && closed)
543 throw new ObjectDisposedException (GetType ().ToString ());
546 IntPtr sock = (IntPtr) (-1);
548 RegisterForBlockingSyscall ();
549 sock = Accept_internal(socket, out error, blocking);
551 UnRegisterForBlockingSyscall ();
556 error = SOCKET_CLOSED;
557 throw new SocketException(error);
560 Socket accepted = new Socket(this.AddressFamily, this.SocketType,
561 this.ProtocolType, sock);
563 accepted.seed_endpoint = this.seed_endpoint;
564 accepted.Blocking = this.Blocking;
568 internal void Accept (Socket acceptSocket)
570 if (disposed && closed)
571 throw new ObjectDisposedException (GetType ().ToString ());
574 IntPtr sock = (IntPtr)(-1);
577 RegisterForBlockingSyscall ();
578 sock = Accept_internal (socket, out error, blocking);
580 UnRegisterForBlockingSyscall ();
585 error = SOCKET_CLOSED;
586 throw new SocketException (error);
589 acceptSocket.address_family = this.AddressFamily;
590 acceptSocket.socket_type = this.SocketType;
591 acceptSocket.protocol_type = this.ProtocolType;
592 acceptSocket.socket = sock;
593 acceptSocket.connected = true;
594 acceptSocket.seed_endpoint = this.seed_endpoint;
595 acceptSocket.Blocking = this.Blocking;
597 /* FIXME: figure out what if anything else
602 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
604 if (disposed && closed)
605 throw new ObjectDisposedException (GetType ().ToString ());
607 if (!isbound || !islistening)
608 throw new InvalidOperationException ();
610 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
613 readQ.Enqueue (req.Worker);
617 socket_pool_queue (Worker.Dispatcher, req);
621 public IAsyncResult BeginAccept (int receiveSize,
622 AsyncCallback callback,
625 if (disposed && closed)
626 throw new ObjectDisposedException (GetType ().ToString ());
629 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
631 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
632 req.Buffer = new byte[receiveSize];
634 req.Size = receiveSize;
635 req.SockFlags = SocketFlags.None;
638 readQ.Enqueue (req.Worker);
642 socket_pool_queue (Worker.Dispatcher, req);
646 public IAsyncResult BeginAccept (Socket acceptSocket,
648 AsyncCallback callback,
651 if (disposed && closed)
652 throw new ObjectDisposedException (GetType ().ToString ());
655 throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
657 if (acceptSocket != null) {
658 if (acceptSocket.disposed && acceptSocket.closed)
659 throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
661 if (acceptSocket.IsBound)
662 throw new InvalidOperationException ();
664 /* For some reason the MS runtime
665 * barfs if the new socket is not TCP,
666 * even though it's just about to blow
667 * away all those parameters
669 if (acceptSocket.ProtocolType != ProtocolType.Tcp)
670 throw new SocketException ((int)SocketError.InvalidArgument);
673 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
674 req.Buffer = new byte[receiveSize];
676 req.Size = receiveSize;
677 req.SockFlags = SocketFlags.None;
678 req.AcceptSocket = acceptSocket;
681 readQ.Enqueue (req.Worker);
685 socket_pool_queue (Worker.Dispatcher, req);
689 public IAsyncResult BeginConnect (IPAddress address, int port,
690 AsyncCallback callback,
693 if (disposed && closed)
694 throw new ObjectDisposedException (GetType ().ToString ());
697 throw new ArgumentNullException ("address");
699 if (address.ToString ().Length == 0)
700 throw new ArgumentException ("The length of the IP address is zero");
702 if (port <= 0 || port > 65535)
703 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
706 throw new InvalidOperationException ();
708 IPEndPoint iep = new IPEndPoint (address, port);
709 return(BeginConnect (iep, callback, state));
712 public IAsyncResult BeginConnect (string host, int port,
713 AsyncCallback callback,
716 if (disposed && closed)
717 throw new ObjectDisposedException (GetType ().ToString ());
720 throw new ArgumentNullException ("host");
722 if (address_family != AddressFamily.InterNetwork &&
723 address_family != AddressFamily.InterNetworkV6)
724 throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
726 if (port <= 0 || port > 65535)
727 throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
730 throw new InvalidOperationException ();
732 return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
735 public IAsyncResult BeginDisconnect (bool reuseSocket,
736 AsyncCallback callback,
739 if (disposed && closed)
740 throw new ObjectDisposedException (GetType ().ToString ());
742 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
743 req.ReuseSocket = reuseSocket;
744 socket_pool_queue (Worker.Dispatcher, req);
748 void CheckRange (byte[] buffer, int offset, int size)
751 throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
753 if (offset > buffer.Length)
754 throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
757 throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
759 if (size > buffer.Length - offset)
760 throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
763 public IAsyncResult BeginReceive(byte[] buffer, int offset,
765 SocketFlags socket_flags,
766 AsyncCallback callback,
769 if (disposed && closed)
770 throw new ObjectDisposedException (GetType ().ToString ());
773 throw new ArgumentNullException ("buffer");
775 CheckRange (buffer, offset, size);
777 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
781 req.SockFlags = socket_flags;
784 readQ.Enqueue (req.Worker);
788 socket_pool_queue (Worker.Dispatcher, req);
792 public IAsyncResult BeginReceive (byte[] buffer, int offset,
793 int size, SocketFlags flags,
794 out SocketError error,
795 AsyncCallback callback,
798 /* As far as I can tell from the docs and from
799 * experimentation, a pointer to the
800 * SocketError parameter is not supposed to be
801 * saved for the async parts. And as we don't
802 * set any socket errors in the setup code, we
803 * just have to set it to Success.
805 error = SocketError.Success;
806 return (BeginReceive (buffer, offset, size, flags, callback, state));
809 [CLSCompliant (false)]
810 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
811 SocketFlags socketFlags,
812 AsyncCallback callback,
815 if (disposed && closed)
816 throw new ObjectDisposedException (GetType ().ToString ());
819 throw new ArgumentNullException ("buffers");
821 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
822 req.Buffers = buffers;
823 req.SockFlags = socketFlags;
826 readQ.Enqueue (req.Worker);
830 socket_pool_queue (Worker.Dispatcher, req);
834 [CLSCompliant (false)]
835 public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
836 SocketFlags socketFlags,
837 out SocketError errorCode,
838 AsyncCallback callback,
841 /* I assume the same SocketError semantics as
844 errorCode = SocketError.Success;
845 return (BeginReceive (buffers, socketFlags, callback, state));
848 public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
850 SocketFlags socket_flags,
851 ref EndPoint remote_end,
852 AsyncCallback callback,
854 if (disposed && closed)
855 throw new ObjectDisposedException (GetType ().ToString ());
858 throw new ArgumentNullException ("buffer");
860 if (remote_end == null)
861 throw new ArgumentNullException ("remote_end");
863 CheckRange (buffer, offset, size);
865 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
869 req.SockFlags = socket_flags;
870 req.EndPoint = remote_end;
873 readQ.Enqueue (req.Worker);
877 socket_pool_queue (Worker.Dispatcher, req);
882 public IAsyncResult BeginReceiveMessageFrom (
883 byte[] buffer, int offset, int size,
884 SocketFlags socketFlags, ref EndPoint remoteEP,
885 AsyncCallback callback, object state)
887 if (disposed && closed)
888 throw new ObjectDisposedException (GetType ().ToString ());
891 throw new ArgumentNullException ("buffer");
893 if (remoteEP == null)
894 throw new ArgumentNullException ("remoteEP");
896 CheckRange (buffer, offset, size);
898 throw new NotImplementedException ();
901 public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
902 AsyncCallback callback, object state)
904 if (disposed && closed)
905 throw new ObjectDisposedException (GetType ().ToString ());
908 throw new ArgumentNullException ("buffer");
910 CheckRange (buffer, offset, size);
913 throw new SocketException ((int)SocketError.NotConnected);
915 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
919 req.SockFlags = socket_flags;
922 writeQ.Enqueue (req.Worker);
923 count = writeQ.Count;
926 socket_pool_queue (Worker.Dispatcher, req);
930 public IAsyncResult BeginSend (byte[] buffer, int offset,
932 SocketFlags socketFlags,
933 out SocketError errorCode,
934 AsyncCallback callback,
938 errorCode = SocketError.NotConnected;
939 throw new SocketException ((int)errorCode);
942 errorCode = SocketError.Success;
944 return (BeginSend (buffer, offset, size, socketFlags, callback,
948 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
949 SocketFlags socketFlags,
950 AsyncCallback callback,
953 if (disposed && closed)
954 throw new ObjectDisposedException (GetType ().ToString ());
957 throw new ArgumentNullException ("buffers");
960 throw new SocketException ((int)SocketError.NotConnected);
962 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
963 req.Buffers = buffers;
964 req.SockFlags = socketFlags;
967 writeQ.Enqueue (req.Worker);
968 count = writeQ.Count;
971 socket_pool_queue (Worker.Dispatcher, req);
975 [CLSCompliant (false)]
976 public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
977 SocketFlags socketFlags,
978 out SocketError errorCode,
979 AsyncCallback callback,
983 errorCode = SocketError.NotConnected;
984 throw new SocketException ((int)errorCode);
987 errorCode = SocketError.Success;
988 return (BeginSend (buffers, socketFlags, callback, state));
991 delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
993 sealed class SendFileAsyncResult : IAsyncResult {
997 public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
1003 public object AsyncState {
1004 get { return ares.AsyncState; }
1007 public WaitHandle AsyncWaitHandle {
1008 get { return ares.AsyncWaitHandle; }
1011 public bool CompletedSynchronously {
1012 get { return ares.CompletedSynchronously; }
1015 public bool IsCompleted {
1016 get { return ares.IsCompleted; }
1019 public SendFileHandler Delegate {
1023 public IAsyncResult Original {
1024 get { return ares; }
1028 public IAsyncResult BeginSendFile (string fileName,
1029 AsyncCallback callback,
1032 if (disposed && closed)
1033 throw new ObjectDisposedException (GetType ().ToString ());
1036 throw new NotSupportedException ();
1038 if (!File.Exists (fileName))
1039 throw new FileNotFoundException ();
1041 return BeginSendFile (fileName, null, null, 0, callback, state);
1044 public IAsyncResult BeginSendFile (string fileName,
1047 TransmitFileOptions flags,
1048 AsyncCallback callback,
1051 if (disposed && closed)
1052 throw new ObjectDisposedException (GetType ().ToString ());
1055 throw new NotSupportedException ();
1057 if (!File.Exists (fileName))
1058 throw new FileNotFoundException ();
1060 SendFileHandler d = new SendFileHandler (SendFile);
1061 return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
1064 public IAsyncResult BeginSendTo(byte[] buffer, int offset,
1066 SocketFlags socket_flags,
1067 EndPoint remote_end,
1068 AsyncCallback callback,
1070 if (disposed && closed)
1071 throw new ObjectDisposedException (GetType ().ToString ());
1074 throw new ArgumentNullException ("buffer");
1076 CheckRange (buffer, offset, size);
1078 SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
1079 req.Buffer = buffer;
1080 req.Offset = offset;
1082 req.SockFlags = socket_flags;
1083 req.EndPoint = remote_end;
1086 writeQ.Enqueue (req.Worker);
1087 count = writeQ.Count;
1090 socket_pool_queue (Worker.Dispatcher, req);
1094 // Creates a new system socket, returning the handle
1095 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1096 private extern static void Bind_internal(IntPtr sock,
1100 public void Bind(EndPoint local_end) {
1101 if (disposed && closed)
1102 throw new ObjectDisposedException (GetType ().ToString ());
1104 if (local_end == null)
1105 throw new ArgumentNullException("local_end");
1109 Bind_internal(socket, local_end.Serialize(), out error);
1111 throw new SocketException (error);
1115 seed_endpoint = local_end;
1118 public void Connect (IPAddress address, int port)
1120 Connect (new IPEndPoint (address, port));
1123 public void Connect (IPAddress[] addresses, int port)
1125 if (disposed && closed)
1126 throw new ObjectDisposedException (GetType ().ToString ());
1128 if (addresses == null)
1129 throw new ArgumentNullException ("addresses");
1131 if (this.AddressFamily != AddressFamily.InterNetwork &&
1132 this.AddressFamily != AddressFamily.InterNetworkV6)
1133 throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
1136 throw new InvalidOperationException ();
1138 /* FIXME: do non-blocking sockets Poll here? */
1140 foreach (IPAddress address in addresses) {
1141 IPEndPoint iep = new IPEndPoint (address, port);
1142 SocketAddress serial = iep.Serialize ();
1144 Connect_internal (socket, serial, out error);
1148 seed_endpoint = iep;
1150 } else if (error != (int)SocketError.InProgress &&
1151 error != (int)SocketError.WouldBlock) {
1156 Poll (-1, SelectMode.SelectWrite);
1157 error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
1161 seed_endpoint = iep;
1167 throw new SocketException (error);
1170 public void Connect (string host, int port)
1172 IPAddress [] addresses = Dns.GetHostAddresses (host);
1173 Connect (addresses, port);
1177 public bool DisconnectAsync (SocketAsyncEventArgs e)
1179 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1180 if (disposed && closed)
1181 throw new ObjectDisposedException (GetType ().ToString ());
1184 e.Worker.Init (this, e, SocketOperation.Disconnect);
1185 socket_pool_queue (Worker.Dispatcher, e.Worker.result);
1190 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1191 extern static void Disconnect_internal(IntPtr sock, bool reuse, out int error);
1193 /* According to the docs, the MS runtime will throw
1194 * PlatformNotSupportedException if the platform is
1195 * newer than w2k. We should be able to cope...
1197 public void Disconnect (bool reuseSocket)
1199 if (disposed && closed)
1200 throw new ObjectDisposedException (GetType ().ToString ());
1204 Disconnect_internal (socket, reuseSocket, out error);
1208 /* ERROR_NOT_SUPPORTED */
1209 throw new PlatformNotSupportedException ();
1211 throw new SocketException (error);
1218 /* Do managed housekeeping here... */
1223 [MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
1224 public SocketInformation DuplicateAndClose (int targetProcessId)
1226 var si = new SocketInformation ();
1228 (islistening ? SocketInformationOptions.Listening : 0) |
1229 (connected ? SocketInformationOptions.Connected : 0) |
1230 (blocking ? 0 : SocketInformationOptions.NonBlocking) |
1231 (useoverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
1233 si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket);
1234 socket = (IntPtr) (-1);
1240 public Socket EndAccept (IAsyncResult result)
1245 return(EndAccept (out buffer, out bytes, result));
1248 public Socket EndAccept (out byte[] buffer, IAsyncResult asyncResult)
1251 return(EndAccept (out buffer, out bytes, asyncResult));
1254 public Socket EndAccept (out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
1256 if (disposed && closed)
1257 throw new ObjectDisposedException (GetType ().ToString ());
1259 if (asyncResult == null)
1260 throw new ArgumentNullException ("asyncResult");
1262 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1264 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1266 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1267 throw InvalidAsyncOp ("EndAccept");
1268 if (!asyncResult.IsCompleted)
1269 asyncResult.AsyncWaitHandle.WaitOne ();
1271 req.CheckIfThrowDelayedException ();
1273 buffer = req.Buffer;
1274 bytesTransferred = req.Total;
1279 public void EndConnect (IAsyncResult result)
1281 if (disposed && closed)
1282 throw new ObjectDisposedException (GetType ().ToString ());
1285 throw new ArgumentNullException ("result");
1287 SocketAsyncResult req = result as SocketAsyncResult;
1289 throw new ArgumentException ("Invalid IAsyncResult", "result");
1291 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1292 throw InvalidAsyncOp ("EndConnect");
1293 if (!result.IsCompleted)
1294 result.AsyncWaitHandle.WaitOne();
1296 req.CheckIfThrowDelayedException();
1300 public void EndDisconnect (IAsyncResult asyncResult)
1302 if (disposed && closed)
1303 throw new ObjectDisposedException (GetType ().ToString ());
1305 if (asyncResult == null)
1306 throw new ArgumentNullException ("asyncResult");
1308 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1310 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1312 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1313 throw InvalidAsyncOp ("EndDisconnect");
1314 if (!asyncResult.IsCompleted)
1315 asyncResult.AsyncWaitHandle.WaitOne ();
1317 req.CheckIfThrowDelayedException ();
1322 public int EndReceiveMessageFrom (IAsyncResult asyncResult,
1323 ref SocketFlags socketFlags,
1324 ref EndPoint endPoint,
1325 out IPPacketInformation ipPacketInformation)
1327 if (disposed && closed)
1328 throw new ObjectDisposedException (GetType ().ToString ());
1330 if (asyncResult == null)
1331 throw new ArgumentNullException ("asyncResult");
1333 if (endPoint == null)
1334 throw new ArgumentNullException ("endPoint");
1336 SocketAsyncResult req = asyncResult as SocketAsyncResult;
1338 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1340 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1341 throw InvalidAsyncOp ("EndReceiveMessageFrom");
1342 throw new NotImplementedException ();
1345 public void EndSendFile (IAsyncResult asyncResult)
1347 if (disposed && closed)
1348 throw new ObjectDisposedException (GetType ().ToString ());
1350 if (asyncResult == null)
1351 throw new ArgumentNullException ("asyncResult");
1353 SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
1355 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
1357 ares.Delegate.EndInvoke (ares.Original);
1361 public int EndSendTo (IAsyncResult result)
1363 if (disposed && closed)
1364 throw new ObjectDisposedException (GetType ().ToString ());
1367 throw new ArgumentNullException ("result");
1369 SocketAsyncResult req = result as SocketAsyncResult;
1371 throw new ArgumentException ("Invalid IAsyncResult", "result");
1373 if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
1374 throw InvalidAsyncOp ("EndSendTo");
1375 if (!result.IsCompleted)
1376 result.AsyncWaitHandle.WaitOne();
1378 req.CheckIfThrowDelayedException();
1383 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1384 private extern static void GetSocketOption_arr_internal(IntPtr socket,
1385 SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
1388 public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
1390 if (disposed && closed)
1391 throw new ObjectDisposedException (GetType ().ToString ());
1393 if (optionValue == null)
1394 throw new SocketException ((int) SocketError.Fault,
1395 "Error trying to dereference an invalid pointer");
1399 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
1402 throw new SocketException (error);
1405 public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
1407 if (disposed && closed)
1408 throw new ObjectDisposedException (GetType ().ToString ());
1410 byte[] byte_val=new byte[length];
1413 GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
1416 throw new SocketException (error);
1421 // See Socket.IOControl, WSAIoctl documentation in MSDN. The
1422 // common options between UNIX and Winsock are FIONREAD,
1423 // FIONBIO and SIOCATMARK. Anything else will depend on the
1424 // system except SIO_KEEPALIVE_VALS which is properly handled
1425 // on both windows and linux.
1426 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1427 extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
1428 byte [] output, out int error);
1430 public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
1433 throw new ObjectDisposedException (GetType ().ToString ());
1436 int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
1440 throw new SocketException (error);
1443 throw new InvalidOperationException ("Must use Blocking property instead.");
1448 public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
1450 return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
1453 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1454 private extern static void Listen_internal(IntPtr sock, int backlog, out int error);
1456 public void Listen (int backlog)
1458 if (disposed && closed)
1459 throw new ObjectDisposedException (GetType ().ToString ());
1462 throw new SocketException ((int)SocketError.InvalidArgument);
1465 Listen_internal(socket, backlog, out error);
1468 throw new SocketException (error);
1473 public bool Poll (int time_us, SelectMode mode)
1475 if (disposed && closed)
1476 throw new ObjectDisposedException (GetType ().ToString ());
1478 if (mode != SelectMode.SelectRead &&
1479 mode != SelectMode.SelectWrite &&
1480 mode != SelectMode.SelectError)
1481 throw new NotSupportedException ("'mode' parameter is not valid.");
1484 bool result = Poll_internal (socket, mode, time_us, out error);
1486 throw new SocketException (error);
1488 if (mode == SelectMode.SelectWrite && result && !connected) {
1489 /* Update the connected state; for
1490 * non-blocking Connect()s this is
1491 * when we can find out that the
1492 * connect succeeded.
1494 if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
1502 public int Receive (byte [] buffer)
1504 if (disposed && closed)
1505 throw new ObjectDisposedException (GetType ().ToString ());
1508 throw new ArgumentNullException ("buffer");
1512 int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
1514 if (error != SocketError.Success)
1515 throw new SocketException ((int) error);
1520 public int Receive (byte [] buffer, SocketFlags flags)
1522 if (disposed && closed)
1523 throw new ObjectDisposedException (GetType ().ToString ());
1526 throw new ArgumentNullException ("buffer");
1530 int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
1532 if (error != SocketError.Success) {
1533 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1534 throw new SocketException ((int) error, "Operation timed out.");
1535 throw new SocketException ((int) error);
1541 public int Receive (byte [] buffer, int size, SocketFlags flags)
1543 if (disposed && closed)
1544 throw new ObjectDisposedException (GetType ().ToString ());
1547 throw new ArgumentNullException ("buffer");
1549 CheckRange (buffer, 0, size);
1553 int ret = Receive_nochecks (buffer, 0, size, flags, out error);
1555 if (error != SocketError.Success) {
1556 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1557 throw new SocketException ((int) error, "Operation timed out.");
1558 throw new SocketException ((int) error);
1564 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
1566 if (disposed && closed)
1567 throw new ObjectDisposedException (GetType ().ToString ());
1570 throw new ArgumentNullException ("buffer");
1572 CheckRange (buffer, offset, size);
1576 int ret = Receive_nochecks (buffer, offset, size, flags, out error);
1578 if (error != SocketError.Success) {
1579 if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
1580 throw new SocketException ((int) error, "Operation timed out.");
1581 throw new SocketException ((int) error);
1587 public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
1589 if (disposed && closed)
1590 throw new ObjectDisposedException (GetType ().ToString ());
1593 throw new ArgumentNullException ("buffer");
1595 CheckRange (buffer, offset, size);
1597 return Receive_nochecks (buffer, offset, size, flags, out error);
1601 public bool ReceiveFromAsync (SocketAsyncEventArgs e)
1603 if (disposed && closed)
1604 throw new ObjectDisposedException (GetType ().ToString ());
1606 // We do not support recv into multiple buffers yet
1607 if (e.BufferList != null)
1608 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1609 if (e.RemoteEndPoint == null)
1610 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1613 e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
1614 SocketAsyncResult res = e.Worker.result;
1615 res.Buffer = e.Buffer;
1616 res.Offset = e.Offset;
1618 res.EndPoint = e.RemoteEndPoint;
1619 res.SockFlags = e.SocketFlags;
1622 readQ.Enqueue (e.Worker);
1623 count = readQ.Count;
1626 socket_pool_queue (Worker.Dispatcher, res);
1631 public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
1633 if (disposed && closed)
1634 throw new ObjectDisposedException (GetType ().ToString ());
1637 throw new ArgumentNullException ("buffer");
1639 if (remoteEP == null)
1640 throw new ArgumentNullException ("remoteEP");
1642 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
1645 public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
1647 if (disposed && closed)
1648 throw new ObjectDisposedException (GetType ().ToString ());
1651 throw new ArgumentNullException ("buffer");
1653 if (remoteEP == null)
1654 throw new ArgumentNullException ("remoteEP");
1656 return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
1659 public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
1660 ref EndPoint remoteEP)
1662 if (disposed && closed)
1663 throw new ObjectDisposedException (GetType ().ToString ());
1666 throw new ArgumentNullException ("buffer");
1668 if (remoteEP == null)
1669 throw new ArgumentNullException ("remoteEP");
1671 if (size < 0 || size > buffer.Length)
1672 throw new ArgumentOutOfRangeException ("size");
1674 return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
1677 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1678 private extern static int RecvFrom_internal(IntPtr sock,
1683 ref SocketAddress sockaddr,
1686 public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
1687 ref EndPoint remoteEP)
1689 if (disposed && closed)
1690 throw new ObjectDisposedException (GetType ().ToString ());
1693 throw new ArgumentNullException ("buffer");
1695 if (remoteEP == null)
1696 throw new ArgumentNullException ("remoteEP");
1698 CheckRange (buffer, offset, size);
1700 return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
1703 internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
1704 ref EndPoint remote_end)
1707 return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
1710 internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
1711 ref EndPoint remote_end, bool throwOnError, out int error)
1713 SocketAddress sockaddr = remote_end.Serialize();
1714 int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
1715 SocketError err = (SocketError) error;
1717 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
1719 else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
1721 throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
1722 error = (int) SocketError.TimedOut;
1727 throw new SocketException (error);
1734 // If sockaddr is null then we're a connection
1735 // oriented protocol and should ignore the
1736 // remote_end parameter (see MSDN
1737 // documentation for Socket.ReceiveFrom(...) )
1739 if ( sockaddr != null ) {
1740 // Stupidly, EndPoint.Create() is an
1742 remote_end = remote_end.Create (sockaddr);
1745 seed_endpoint = remote_end;
1750 [MonoTODO ("Not implemented")]
1751 public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
1753 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1754 if (disposed && closed)
1755 throw new ObjectDisposedException (GetType ().ToString ());
1757 throw new NotImplementedException ();
1760 [MonoTODO ("Not implemented")]
1761 public int ReceiveMessageFrom (byte[] buffer, int offset,
1763 ref SocketFlags socketFlags,
1764 ref EndPoint remoteEP,
1765 out IPPacketInformation ipPacketInformation)
1767 if (disposed && closed)
1768 throw new ObjectDisposedException (GetType ().ToString ());
1771 throw new ArgumentNullException ("buffer");
1773 if (remoteEP == null)
1774 throw new ArgumentNullException ("remoteEP");
1776 CheckRange (buffer, offset, size);
1778 /* FIXME: figure out how we get hold of the
1779 * IPPacketInformation
1781 throw new NotImplementedException ();
1784 [MonoTODO ("Not implemented")]
1785 public bool SendPacketsAsync (SocketAsyncEventArgs e)
1787 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1789 if (disposed && closed)
1790 throw new ObjectDisposedException (GetType ().ToString ());
1792 throw new NotImplementedException ();
1795 public int Send (byte [] buf)
1797 if (disposed && closed)
1798 throw new ObjectDisposedException (GetType ().ToString ());
1801 throw new ArgumentNullException ("buf");
1805 int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
1807 if (error != SocketError.Success)
1808 throw new SocketException ((int) error);
1813 public int Send (byte [] buf, SocketFlags flags)
1815 if (disposed && closed)
1816 throw new ObjectDisposedException (GetType ().ToString ());
1819 throw new ArgumentNullException ("buf");
1823 int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
1825 if (error != SocketError.Success)
1826 throw new SocketException ((int) error);
1831 public int Send (byte [] buf, int size, SocketFlags flags)
1833 if (disposed && closed)
1834 throw new ObjectDisposedException (GetType ().ToString ());
1837 throw new ArgumentNullException ("buf");
1839 CheckRange (buf, 0, size);
1843 int ret = Send_nochecks (buf, 0, size, flags, out error);
1845 if (error != SocketError.Success)
1846 throw new SocketException ((int) error);
1851 public int Send (byte [] buf, int offset, int size, SocketFlags flags)
1853 if (disposed && closed)
1854 throw new ObjectDisposedException (GetType ().ToString ());
1857 throw new ArgumentNullException ("buffer");
1859 CheckRange (buf, offset, size);
1863 int ret = Send_nochecks (buf, offset, size, flags, out error);
1865 if (error != SocketError.Success)
1866 throw new SocketException ((int) error);
1871 public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
1873 if (disposed && closed)
1874 throw new ObjectDisposedException (GetType ().ToString ());
1877 throw new ArgumentNullException ("buffer");
1879 CheckRange (buf, offset, size);
1881 return Send_nochecks (buf, offset, size, flags, out error);
1884 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1885 private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
1887 public void SendFile (string fileName)
1889 if (disposed && closed)
1890 throw new ObjectDisposedException (GetType ().ToString ());
1893 throw new NotSupportedException ();
1896 throw new InvalidOperationException ();
1898 SendFile (fileName, null, null, 0);
1901 public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
1903 if (disposed && closed)
1904 throw new ObjectDisposedException (GetType ().ToString ());
1907 throw new NotSupportedException ();
1910 throw new InvalidOperationException ();
1912 if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
1913 SocketException exc = new SocketException ();
1914 if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
1915 throw new FileNotFoundException ();
1921 public bool SendToAsync (SocketAsyncEventArgs e)
1923 // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
1925 if (disposed && closed)
1926 throw new ObjectDisposedException (GetType ().ToString ());
1927 if (e.BufferList != null)
1928 throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
1929 if (e.RemoteEndPoint == null)
1930 throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
1933 e.Worker.Init (this, e, SocketOperation.SendTo);
1934 SocketAsyncResult res = e.Worker.result;
1935 res.Buffer = e.Buffer;
1936 res.Offset = e.Offset;
1938 res.SockFlags = e.SocketFlags;
1939 res.EndPoint = e.RemoteEndPoint;
1942 writeQ.Enqueue (e.Worker);
1943 count = writeQ.Count;
1946 socket_pool_queue (Worker.Dispatcher, res);
1951 public int SendTo (byte [] buffer, EndPoint remote_end)
1953 if (disposed && closed)
1954 throw new ObjectDisposedException (GetType ().ToString ());
1957 throw new ArgumentNullException ("buffer");
1959 if (remote_end == null)
1960 throw new ArgumentNullException ("remote_end");
1962 return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
1965 public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
1967 if (disposed && closed)
1968 throw new ObjectDisposedException (GetType ().ToString ());
1971 throw new ArgumentNullException ("buffer");
1973 if (remote_end == null)
1974 throw new ArgumentNullException ("remote_end");
1976 return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
1979 public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
1981 if (disposed && closed)
1982 throw new ObjectDisposedException (GetType ().ToString ());
1985 throw new ArgumentNullException ("buffer");
1987 if (remote_end == null)
1988 throw new ArgumentNullException ("remote_end");
1990 CheckRange (buffer, 0, size);
1992 return SendTo_nochecks (buffer, 0, size, flags, remote_end);
1995 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1996 private extern static int SendTo_internal(IntPtr sock,
2004 public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
2005 EndPoint remote_end)
2007 if (disposed && closed)
2008 throw new ObjectDisposedException (GetType ().ToString ());
2011 throw new ArgumentNullException ("buffer");
2013 if (remote_end == null)
2014 throw new ArgumentNullException("remote_end");
2016 CheckRange (buffer, offset, size);
2018 return SendTo_nochecks (buffer, offset, size, flags, remote_end);
2021 internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
2022 EndPoint remote_end)
2024 SocketAddress sockaddr = remote_end.Serialize ();
2028 ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
2030 SocketError err = (SocketError) error;
2032 if (err != SocketError.WouldBlock && err != SocketError.InProgress)
2035 throw new SocketException (error);
2040 seed_endpoint = remote_end;
2045 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
2047 if (disposed && closed)
2048 throw new ObjectDisposedException (GetType ().ToString ());
2050 // I'd throw an ArgumentNullException, but this is what MS does.
2051 if (optionValue == null)
2052 throw new SocketException ((int) SocketError.Fault,
2053 "Error trying to dereference an invalid pointer");
2057 SetSocketOption_internal (socket, optionLevel, optionName, null,
2058 optionValue, 0, out error);
2061 if (error == (int) SocketError.InvalidArgument)
2062 throw new ArgumentException ();
2063 throw new SocketException (error);
2067 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
2069 if (disposed && closed)
2070 throw new ObjectDisposedException (GetType ().ToString ());
2072 // NOTE: if a null is passed, the byte[] overload is used instead...
2073 if (optionValue == null)
2074 throw new ArgumentNullException("optionValue");
2078 if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
2079 LingerOption linger = optionValue as LingerOption;
2081 throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
2082 SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
2083 } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2084 MulticastOption multicast = optionValue as MulticastOption;
2085 if (multicast == null)
2086 throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
2087 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2088 } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
2089 IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
2090 if (multicast == null)
2091 throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
2092 SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
2094 throw new ArgumentException ("Invalid value specified.", "optionValue");
2098 if (error == (int) SocketError.InvalidArgument)
2099 throw new ArgumentException ();
2100 throw new SocketException (error);
2104 public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
2106 if (disposed && closed)
2107 throw new ObjectDisposedException (GetType ().ToString ());
2110 int int_val = (optionValue) ? 1 : 0;
2111 SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
2113 if (error == (int) SocketError.InvalidArgument)
2114 throw new ArgumentException ();
2115 throw new SocketException (error);