13 internal class AsyncStateObject
15 internal byte[] buffer;
17 internal string hostName;
23 internal object userToken;
25 internal AsyncStateObject(
string hostName,
byte[] buffer,
int timeout,
PingOptions options,
object userToken)
27 this.hostName = hostName;
29 this.timeout = timeout;
30 this.options = options;
31 this.userToken = userToken;
35 private const int MaxUdpPacket = 65791;
37 private const int MaxBufferSize = 65500;
39 private const int DefaultTimeout = 5000;
41 private const int DefaultSendBufferSize = 32;
43 private byte[] defaultSendBuffer;
47 private bool cancelled;
49 private bool disposeRequested;
51 private object lockObject =
new object();
57 private SafeLocalFree requestBuffer;
59 private SafeLocalFree replyBuffer;
63 private SafeCloseIcmpHandle handlePingV4;
65 private SafeCloseIcmpHandle handlePingV6;
73 private const int Free = 0;
75 private const int InProgress = 1;
77 private new const int Disposed = 2;
81 private bool InAsyncCall
85 if (asyncFinished ==
null)
89 return !asyncFinished.
WaitOne(0);
93 if (asyncFinished ==
null)
99 asyncFinished.
Reset();
108 private byte[] DefaultSendBuffer
112 if (defaultSendBuffer ==
null)
114 defaultSendBuffer =
new byte[32];
115 for (
int i = 0; i < 32; i++)
117 defaultSendBuffer[i] = (byte)(97 + i % 23);
120 return defaultSendBuffer;
127 private void CheckStart(
bool async)
129 if (disposeRequested)
146 private void Finish(
bool async)
153 if (disposeRequested)
163 if (this.PingCompleted !=
null)
169 private void PingCompletedWaitCallback(
object operationState)
177 onPingCompletedDelegate = PingCompletedWaitCallback;
180 private void InternalDispose()
182 disposeRequested =
true;
185 if (handlePingV4 !=
null)
187 handlePingV4.Close();
190 if (handlePingV6 !=
null)
192 handlePingV6.Close();
195 UnregisterWaitHandle();
196 if (pingEvent !=
null)
201 if (replyBuffer !=
null)
206 if (asyncFinished !=
null)
208 asyncFinished.
Close();
209 asyncFinished =
null;
214 private void UnregisterWaitHandle()
218 if (registeredWait !=
null)
221 registeredWait =
null;
229 protected override void Dispose(
bool disposing)
235 base.Dispose(disposing);
252 private static void PingCallback(
object state,
bool signaled)
261 lock (ping.lockObject)
263 flag = ping.cancelled;
264 asyncOperation = ping.asyncOp;
265 d = ping.onPingCompletedDelegate;
268 SafeLocalFree safeLocalFree = ping.replyBuffer;
272 Icmp6EchoReply reply = (Icmp6EchoReply)
Marshal.
PtrToStructure(safeLocalFree.DangerousGetHandle(), typeof(Icmp6EchoReply));
273 reply2 =
new PingReply(reply, safeLocalFree.DangerousGetHandle(), ping.sendSize);
277 IcmpEchoReply reply3 = (IcmpEchoReply)
Marshal.
PtrToStructure(safeLocalFree.DangerousGetHandle(), typeof(IcmpEchoReply));
278 reply2 =
new PingReply(reply3);
280 arg =
new PingCompletedEventArgs(reply2,
null, cancelled:
false, asyncOperation.
UserSuppliedState);
284 arg =
new PingCompletedEventArgs(
null,
null, cancelled:
true, asyncOperation.
UserSuppliedState);
288 catch (Exception innerException)
290 PingException error =
new PingException(SR.GetString(
"net_ping"), innerException);
291 arg =
new PingCompletedEventArgs(
null, error, cancelled:
false, asyncOperation.
UserSuppliedState);
295 ping.FreeUnmanagedStructures();
296 ping.UnregisterWaitHandle();
297 ping.Finish(async:
true);
314 return Send(hostNameOrAddress, 5000, DefaultSendBuffer,
null);
330 return Send(hostNameOrAddress, timeout, DefaultSendBuffer,
null);
345 return Send(address, 5000, DefaultSendBuffer,
null);
363 return Send(address, timeout, DefaultSendBuffer,
null);
382 return Send(hostNameOrAddress, timeout, buffer,
null);
403 return Send(address, timeout, buffer,
null);
425 if (ValidationHelper.IsBlankString(hostNameOrAddress))
441 throw new PingException(SR.GetString(
"net_ping"), innerException);
444 return Send(address, timeout, buffer, options);
470 if (buffer.Length > 65500)
472 throw new ArgumentException(SR.GetString(
"net_invalidPingBufferSize"),
"buffer");
482 TestIsIpSupported(address);
489 CheckStart(async:
false);
492 return InternalSend(address2, buffer, timeout, options, async:
false);
496 throw new PingException(SR.GetString(
"net_ping"), innerException);
500 Finish(async:
false);
516 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
517 public void SendAsync(
string hostNameOrAddress,
object userToken)
519 SendAsync(hostNameOrAddress, 5000, DefaultSendBuffer, userToken);
537 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
538 public void SendAsync(
string hostNameOrAddress,
int timeout,
object userToken)
540 SendAsync(hostNameOrAddress, timeout, DefaultSendBuffer, userToken);
555 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
558 SendAsync(address, 5000, DefaultSendBuffer, userToken);
576 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
579 SendAsync(address, timeout, DefaultSendBuffer, userToken);
600 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
601 public void SendAsync(
string hostNameOrAddress,
int timeout,
byte[] buffer,
object userToken)
603 SendAsync(hostNameOrAddress, timeout, buffer,
null, userToken);
624 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
627 SendAsync(address, timeout, buffer,
null, userToken);
649 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
650 public void SendAsync(
string hostNameOrAddress,
int timeout,
byte[] buffer,
PingOptions options,
object userToken)
652 if (ValidationHelper.IsBlankString(hostNameOrAddress))
660 if (buffer.Length > 65500)
662 throw new ArgumentException(SR.GetString(
"net_invalidPingBufferSize"),
"buffer");
670 SendAsync(address, timeout, buffer, options, userToken);
673 CheckStart(async:
true);
678 AsyncStateObject state =
new AsyncStateObject(hostNameOrAddress, buffer, timeout, options, userToken);
684 throw new PingException(SR.GetString(
"net_ping"), innerException);
707 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
714 if (buffer.Length > 65500)
716 throw new ArgumentException(SR.GetString(
"net_invalidPingBufferSize"),
"buffer");
726 TestIsIpSupported(address);
733 CheckStart(async:
true);
738 InternalSend(address2, buffer, timeout, options, async:
true);
743 throw new PingException(SR.GetString(
"net_ping"), innerException);
757 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
769 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
782 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
795 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
800 SendAsync(hostNameOrAddress, timeout, tcs);
820 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
825 SendAsync(address, timeout, buffer, tcs);
834 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
839 SendAsync(hostNameOrAddress, timeout, buffer, tcs);
860 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
865 SendAsync(address, timeout, buffer, options, tcs);
875 [HostProtection(
SecurityAction.LinkDemand, ExternalThreading =
true)]
880 SendAsync(hostNameOrAddress, timeout, buffer, options, tcs);
890 HandleCompletion(tcs, e, handler);
907 if (e.UserState == tcs)
919 else if (e.Cancelled)
931 private void ContinueAsyncSend(
object state)
933 AsyncStateObject asyncStateObject = (AsyncStateObject)state;
936 IPAddress address =
Dns.GetHostAddresses(asyncStateObject.hostName)[0];
938 InternalSend(address, asyncStateObject.buffer, asyncStateObject.timeout, asyncStateObject.options, async:
true);
940 catch (Exception innerException)
942 PingException error =
new PingException(SR.GetString(
"net_ping"), innerException);
943 PingCompletedEventArgs arg =
new PingCompletedEventArgs(
null, error, cancelled:
false, asyncOp.
UserSuppliedState);
949 private PingReply InternalSend(IPAddress address,
byte[] buffer,
int timeout, PingOptions options,
bool async)
951 ipv6 = ((address.AddressFamily ==
AddressFamily.InterNetworkV6) ?
true :
false);
952 sendSize = buffer.Length;
953 if (!ipv6 && handlePingV4 ==
null)
955 handlePingV4 = UnsafeNetInfoNativeMethods.IcmpCreateFile();
956 if (handlePingV4.IsInvalid)
962 else if (ipv6 && handlePingV6 ==
null)
964 handlePingV6 = UnsafeNetInfoNativeMethods.Icmp6CreateFile();
965 if (handlePingV6.IsInvalid)
972 if (replyBuffer ==
null)
974 replyBuffer = SafeLocalFree.LocalAlloc(65791);
981 if (pingEvent ==
null)
991 SetUnmanagedStructures(buffer);
994 num = (int)((!async) ? UnsafeNetInfoNativeMethods.IcmpSendEcho2(handlePingV4, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref options2, replyBuffer, 65791u, (uint)timeout) : UnsafeNetInfoNativeMethods.IcmpSendEcho2(handlePingV4, pingEvent.
SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref options2, replyBuffer, 65791u, (uint)timeout));
998 IPEndPoint iPEndPoint =
new IPEndPoint(address, 0);
999 SocketAddress socketAddress = iPEndPoint.Serialize();
1000 byte[] sourceSocketAddress =
new byte[28];
1001 num = (int)((!async) ? UnsafeNetInfoNativeMethods.Icmp6SendEcho2(handlePingV6, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, sourceSocketAddress, socketAddress.m_Buffer, requestBuffer, (ushort)buffer.Length, ref options2, replyBuffer, 65791u, (uint)timeout) : UnsafeNetInfoNativeMethods.Icmp6SendEcho2(handlePingV6, pingEvent.
SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, sourceSocketAddress, socketAddress.m_Buffer, requestBuffer, (ushort)buffer.Length, ref options2, replyBuffer, 65791u, (uint)timeout));
1006 UnregisterWaitHandle();
1012 if (async && (
long)num == 997)
1016 FreeUnmanagedStructures();
1017 UnregisterWaitHandle();
1018 if (async || num < 11002 || num > 11045)
1022 return new PingReply((
IPStatus)num);
1028 FreeUnmanagedStructures();
1032 Icmp6EchoReply reply = (Icmp6EchoReply)
Marshal.
PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(Icmp6EchoReply));
1033 result =
new PingReply(reply, replyBuffer.DangerousGetHandle(), sendSize);
1037 IcmpEchoReply reply2 = (IcmpEchoReply)
Marshal.
PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(IcmpEchoReply));
1038 result =
new PingReply(reply2);
1040 GC.KeepAlive(replyBuffer);
1044 private void TestIsIpSupported(IPAddress ip)
1048 throw new NotSupportedException(SR.GetString(
"net_ipv4_not_installed"));
1052 throw new NotSupportedException(SR.GetString(
"net_ipv6_not_installed"));
1056 private unsafe
void SetUnmanagedStructures(
byte[] buffer)
1058 requestBuffer = SafeLocalFree.LocalAlloc(buffer.Length);
1059 byte* ptr = (
byte*)(
void*)requestBuffer.DangerousGetHandle();
1060 for (
int i = 0; i < buffer.Length; i++)
1066 private void FreeUnmanagedStructures()
1068 if (requestBuffer !=
null)
1070 requestBuffer.Close();
1071 requestBuffer =
null;
Provides concurrency management for classes that support asynchronous method calls....
The host name is a domain name system (DNS) style host name.
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Represents a handle that has been registered when calling M:System.Threading.ThreadPool....
delegate void SendOrPostCallback(object state)
Represents a method to be called when a message is to be dispatched to a synchronization context.
static bool QueueUserWorkItem(WaitCallback callBack, object state)
Queues a method for execution, and specifies an object containing data to be used by the method....
SafeWaitHandle SafeWaitHandle
Gets or sets the native operating system handle.
Tracks the lifetime of an asynchronous operation.
bool Set()
Sets the state of the event to signaled, allowing one or more waiting threads to proceed.
static readonly IPAddress Any
Provides an IP address that indicates that the server must listen for client activity on all network ...
The exception that is thrown when the value of an argument is outside the allowable range of values a...
Implements the Berkeley sockets interface.
delegate void Action()
Encapsulates a method that has no parameters and does not return a value.
static bool TryParse(string ipString, out IPAddress address)
Determines whether a string is a valid IP address.
virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
Blocks the current thread until the current T:System.Threading.WaitHandle receives a signal,...
AddressFamily AddressFamily
Gets the address family of the IP address.
static IPAddress [] GetHostAddresses(string hostNameOrAddress)
Returns the Internet Protocol (IP) addresses for the specified host.
The exception that is thrown when an operation is performed on a disposed object.
Provides an Internet Protocol (IP) address.
SecurityAction
Specifies the security actions that can be performed using declarative security.
bool TrySetResult(TResult result)
Attempts to transition the underlying T:System.Threading.Tasks.Task`1 into the F:System....
bool TrySetException(Exception exception)
Attempts to transition the underlying T:System.Threading.Tasks.Task`1 into the F:System....
static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce)
Registers a delegate to wait for a T:System.Threading.WaitHandle, specifying a 32-bit unsigned intege...
Throws an exception for a Win32 error code.
static readonly IPAddress IPv6Any
The M:System.Net.Sockets.Socket.Bind(System.Net.EndPoint) method uses the F:System....
AddressFamily
Specifies the addressing scheme that an instance of the T:System.Net.Sockets.Socket class can use.
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
Notifies one or more waiting threads that an event has occurred. This class cannot be inherited.
Represents the producer side of a T:System.Threading.Tasks.Task`1 unbound to a delegate,...
Provides the base implementation for the T:System.ComponentModel.IComponent interface and enables obj...
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Task< TResult > Task
Gets the T:System.Threading.Tasks.Task`1 created by this T:System.Threading.Tasks....
virtual void Close()
Releases all resources held by the current T:System.Threading.WaitHandle.
long ScopeId
Gets or sets the IPv6 address scope identifier.
The exception that is thrown when one of the arguments provided to a method is not valid.
void Demand()
Forces a T:System.Security.SecurityException at run time if all callers higher in the call stack have...
static void PtrToStructure(IntPtr ptr, object structure)
Marshals data from an unmanaged block of memory to a managed object.
byte [] GetAddressBytes()
Provides a copy of the T:System.Net.IPAddress as an array of bytes.
Represents errors that occur during application execution.To browse the .NET Framework source code fo...
static AsyncOperation CreateOperation(object userSuppliedState)
Returns an T:System.ComponentModel.AsyncOperation for tracking the duration of a particular asynchron...
object UserSuppliedState
Gets or sets an object used to uniquely identify an asynchronous operation.
void PostOperationCompleted(SendOrPostCallback d, object arg)
Ends the lifetime of an asynchronous operation.
The exception that is thrown when a method call is invalid for the object's current state.
Provides simple domain name resolution functionality.
static bool OSSupportsIPv6
Indicates whether the underlying operating system and network adaptors support Internet Protocol vers...
bool TrySetCanceled()
Attempts to transition the underlying T:System.Threading.Tasks.Task`1 into the F:System....
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
Provides atomic operations for variables that are shared by multiple threads.
bool Reset()
Sets the state of the event to nonsignaled, causing threads to block.
Provides a pool of threads that can be used to execute tasks, post work items, process asynchronous I...
Represents an asynchronous operation that can return a value.
Specifies the IP options to be inserted into outgoing datagrams.
bool Unregister(WaitHandle waitObject)
Cancels a registered wait operation issued by the M:System.Threading.ThreadPool.RegisterWaitForSingle...
static bool OSSupportsIPv4
Indicates whether the underlying operating system and network adaptors support Internet Protocol vers...