forked from BornToBeRoot/NETworkManager
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPing.cs
More file actions
158 lines (131 loc) · 5.55 KB
/
Copy pathPing.cs
File metadata and controls
158 lines (131 loc) · 5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace NETworkManager.Models.Network
{
public class Ping
{
#region Varaibles
public int WaitTime = 1000;
public int Timeout = 4000;
public byte[] Buffer = new byte[32];
public int TTL = 64;
public bool DontFragment = true;
public int ExceptionCancelCount = 3;
public string Hostname = string.Empty;
#endregion
#region Events
public event EventHandler<PingReceivedArgs> PingReceived;
protected virtual void OnPingReceived(PingReceivedArgs e)
{
PingReceived?.Invoke(this, e);
}
public event EventHandler PingCompleted;
protected virtual void OnPingCompleted()
{
PingCompleted?.Invoke(this, EventArgs.Empty);
}
public event EventHandler<PingExceptionArgs> PingException;
protected virtual void OnPingException(PingExceptionArgs e)
{
PingException?.Invoke(this, e);
}
public event EventHandler UserHasCanceled;
protected virtual void OnUserHasCanceled()
{
UserHasCanceled?.Invoke(this, EventArgs.Empty);
}
#endregion
#region Methods
public void SendAsync(IPAddress ipAddress, CancellationToken cancellationToken)
{
Task.Run(() =>
{
var hostname = Hostname;
// Try to resolve PTR
if (string.IsNullOrEmpty(hostname))
{
try
{
Task.Run(() =>
{
hostname = Dns.GetHostEntryAsync(ipAddress).Result.HostName;
}, cancellationToken);
}
catch (SocketException) { }
}
var pingTotal = 0;
var errorCount = 0;
var options = new PingOptions
{
Ttl = TTL,
DontFragment = DontFragment
};
using (var ping = new System.Net.NetworkInformation.Ping())
{
do
{
try
{
// Get timestamp
var timestamp = DateTime.Now;
// Send ping
var pingReply = ping.Send(ipAddress, Timeout, Buffer, options);
// Reset the error count (if no exception was thrown)
errorCount = 0;
if (pingReply == null || pingReply.Status != IPStatus.Success)
{
if (pingReply != null && pingReply.Address == null)
OnPingReceived(new PingReceivedArgs(timestamp, ipAddress, hostname, pingReply.Status));
else if (pingReply != null)
OnPingReceived(new PingReceivedArgs(timestamp, pingReply.Address, hostname, pingReply.Status));
}
else
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
OnPingReceived(new PingReceivedArgs(timestamp, pingReply.Address, hostname,
pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl, pingReply.Status));
else
OnPingReceived(new PingReceivedArgs(timestamp, pingReply.Address, hostname,
pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Status));
}
}
catch (PingException ex)
{
errorCount++;
if (errorCount == ExceptionCancelCount)
{
OnPingException(new PingExceptionArgs(ex.Message, ex.InnerException));
break;
}
}
pingTotal++;
// If ping is canceled... dont wait for example 5 seconds
for (var i = 0; i < WaitTime; i += 100)
{
Thread.Sleep(100);
if (cancellationToken.IsCancellationRequested)
break;
}
} while (!cancellationToken.IsCancellationRequested);
}
if (cancellationToken.IsCancellationRequested)
OnUserHasCanceled();
else
OnPingCompleted();
}, cancellationToken);
}
// Param: disableSpecialChar --> ExportManager --> "<" this char cannot be displayed in xml
public static string TimeToString(IPStatus status, long time, bool disableSpecialChar = false)
{
if (status != IPStatus.Success && status != IPStatus.TtlExpired)
return "-/-";
long.TryParse(time.ToString(), out var t);
return disableSpecialChar ? $"{t} ms" : t == 0 ? "<1 ms" : $"{t} ms";
}
#endregion
}
}