1 // System.Net.Sockets.SocketAsyncEventArgs.cs
4 // Marek Habersack (mhabersack@novell.com)
5 // Gonzalo Paniagua Javier (gonzalo@novell.com)
7 // Copyright (c) 2008,2010 Novell, Inc. (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections.Generic;
32 using System.Reflection;
33 using System.Security;
34 using System.Threading;
36 namespace System.Net.Sockets
38 public class SocketAsyncEventArgs : EventArgs, IDisposable
40 internal Socket.Worker Worker;
42 #if MOONLIGHT || NET_4_0
43 public Exception ConnectByNameError { get; internal set; }
46 public event EventHandler<SocketAsyncEventArgs> Completed;
48 IList <ArraySegment <byte>> _bufferList;
50 public Socket AcceptSocket { get; set; }
51 public byte[] Buffer { get; private set; }
53 public IList<ArraySegment<byte>> BufferList {
54 get { return _bufferList; }
56 if (Buffer != null && value != null)
57 throw new ArgumentException ("Buffer and BufferList properties cannot both be non-null.");
62 public int BytesTransferred { get; internal set; }
63 public int Count { get; internal set; }
64 public bool DisconnectReuseSocket { get; set; }
65 public SocketAsyncOperation LastOperation { get; private set; }
66 public int Offset { get; private set; }
67 public EndPoint RemoteEndPoint {
68 get { return remote_ep; }
69 set { remote_ep = value; }
72 public IPPacketInformation ReceiveMessageFromPacketInfo { get; private set; }
73 public SendPacketsElement[] SendPacketsElements { get; set; }
74 public TransmitFileOptions SendPacketsFlags { get; set; }
76 [MonoTODO ("unused property")]
77 public int SendPacketsSendSize { get; set; }
78 public SocketError SocketError { get; set; }
79 public SocketFlags SocketFlags { get; set; }
80 public object UserToken { get; set; }
82 #if MOONLIGHT && !INSIDE_SYSTEM
83 private SocketClientAccessPolicyProtocol policy_protocol;
85 public SocketClientAccessPolicyProtocol SocketClientAccessPolicyProtocol {
86 get { return policy_protocol; }
88 if ((value != SocketClientAccessPolicyProtocol.Tcp) && (value != SocketClientAccessPolicyProtocol.Http))
89 throw new ArgumentException ("Invalid value");
90 policy_protocol = value;
95 internal Socket curSocket;
97 public Socket ConnectSocket {
99 switch (SocketError) {
100 case SocketError.AccessDenied:
108 internal bool PolicyRestricted { get; private set; }
110 internal SocketAsyncEventArgs (bool policy) :
113 PolicyRestricted = policy;
117 public SocketAsyncEventArgs ()
119 Worker = new Socket.Worker (this);
123 BytesTransferred = 0;
125 DisconnectReuseSocket = false;
126 LastOperation = SocketAsyncOperation.None;
128 RemoteEndPoint = null;
130 SendPacketsElements = null;
131 SendPacketsFlags = TransmitFileOptions.UseDefaultWorkerThread;
133 SendPacketsSendSize = -1;
134 SocketError = SocketError.Success;
135 SocketFlags = SocketFlags.None;
138 #if MOONLIGHT && !INSIDE_SYSTEM
139 policy_protocol = SocketClientAccessPolicyProtocol.Tcp;
143 ~SocketAsyncEventArgs ()
148 void Dispose (bool disposing)
151 if (Worker != null) {
159 RemoteEndPoint = null;
162 SendPacketsElements = null;
166 public void Dispose ()
169 GC.SuppressFinalize (this);
172 internal void SetLastOperation (SocketAsyncOperation op)
177 protected virtual void OnCompleted (SocketAsyncEventArgs e)
182 EventHandler<SocketAsyncEventArgs> handler = e.Completed;
184 handler (e.curSocket, e);
187 public void SetBuffer (int offset, int count)
189 SetBufferInternal (Buffer, offset, count);
192 public void SetBuffer (byte[] buffer, int offset, int count)
194 SetBufferInternal (buffer, offset, count);
197 void SetBufferInternal (byte[] buffer, int offset, int count)
199 if (buffer != null) {
200 if (BufferList != null)
201 throw new ArgumentException ("Buffer and BufferList properties cannot both be non-null.");
203 int buflen = buffer.Length;
204 if (offset < 0 || (offset != 0 && offset >= buflen))
205 throw new ArgumentOutOfRangeException ("offset");
207 if (count < 0 || count > buflen - offset)
208 throw new ArgumentOutOfRangeException ("count");
217 internal static AsyncCallback Dispatcher = new AsyncCallback (DispatcherCB);
219 static void DispatcherCB (IAsyncResult ares)
221 SocketAsyncEventArgs args = (SocketAsyncEventArgs) ares.AsyncState;
222 SocketAsyncOperation op = args.LastOperation;
224 // -SocketOperation.AcceptReceive not used in SocketAsyncEventArgs
225 // -SendPackets and ReceiveMessageFrom are not implemented yet
226 if (op == SocketAsyncOperation.Receive)
227 args.ReceiveCallback (ares);
228 else if (op == SocketAsyncOperation.Send)
229 args.SendCallback (ares);
231 else if (op == SocketAsyncOperation.ReceiveFrom)
232 args.ReceiveFromCallback (ares);
233 else if (op == SocketAsyncOperation.SendTo)
234 args.SendToCallback (ares);
235 else if (op == SocketAsyncOperation.Accept)
236 args.AcceptCallback (ares);
237 else if (op == SocketAsyncOperation.Disconnect)
238 args.DisconnectCallback (ares);
240 else if (op == SocketAsyncOperation.Connect)
241 args.ConnectCallback ();
243 else if (op == Socket.SocketOperation.ReceiveMessageFrom)
244 else if (op == Socket.SocketOperation.SendPackets)
247 throw new NotImplementedException (String.Format ("Operation {0} is not implemented", op));
251 internal void ReceiveCallback (IAsyncResult ares)
254 BytesTransferred = curSocket.EndReceive (ares);
255 } catch (SocketException se){
256 SocketError = se.SocketErrorCode;
257 } catch (ObjectDisposedException) {
258 SocketError = SocketError.OperationAborted;
264 void ConnectCallback ()
267 SocketError = (SocketError) Worker.result.error;
273 internal void SendCallback (IAsyncResult ares)
276 BytesTransferred = curSocket.EndSend (ares);
277 } catch (SocketException se){
278 SocketError = se.SocketErrorCode;
279 } catch (ObjectDisposedException) {
280 SocketError = SocketError.OperationAborted;
287 internal void AcceptCallback (IAsyncResult ares)
290 AcceptSocket = curSocket.EndAccept (ares);
291 } catch (SocketException ex) {
292 SocketError = ex.SocketErrorCode;
293 } catch (ObjectDisposedException) {
294 SocketError = SocketError.OperationAborted;
296 if (AcceptSocket == null)
297 AcceptSocket = new Socket (curSocket.AddressFamily, curSocket.SocketType, curSocket.ProtocolType, (IntPtr)(-1));
302 internal void DisconnectCallback (IAsyncResult ares)
305 curSocket.EndDisconnect (ares);
306 } catch (SocketException ex) {
307 SocketError = ex.SocketErrorCode;
308 } catch (ObjectDisposedException) {
309 SocketError = SocketError.OperationAborted;
315 internal void ReceiveFromCallback (IAsyncResult ares)
318 BytesTransferred = curSocket.EndReceiveFrom (ares, ref remote_ep);
319 } catch (SocketException ex) {
320 SocketError = ex.SocketErrorCode;
321 } catch (ObjectDisposedException) {
322 SocketError = SocketError.OperationAborted;
328 internal void SendToCallback (IAsyncResult ares)
331 BytesTransferred = curSocket.EndSendTo (ares);
332 } catch (SocketException ex) {
333 SocketError = ex.SocketErrorCode;
334 } catch (ObjectDisposedException) {
335 SocketError = SocketError.OperationAborted;