diff --git a/Shtirlitz.Library/Reporter/PingReporter/IPingReporterProvider.cs b/Shtirlitz.Library/Reporter/PingReporter/IPingReporterProvider.cs new file mode 100644 index 0000000..279e274 --- /dev/null +++ b/Shtirlitz.Library/Reporter/PingReporter/IPingReporterProvider.cs @@ -0,0 +1,9 @@ +namespace Shtirlitz.Reporter.PingReporter +{ + public interface IPingReporterProvider + { + bool Next(); + PingResult Current { get; } + double Weight { get; } + } +} \ No newline at end of file diff --git a/Shtirlitz.Library/Reporter/PingReporter/PingProvider.cs b/Shtirlitz.Library/Reporter/PingReporter/PingProvider.cs new file mode 100644 index 0000000..c3727d4 --- /dev/null +++ b/Shtirlitz.Library/Reporter/PingReporter/PingProvider.cs @@ -0,0 +1,79 @@ +using System.Net.NetworkInformation; + +namespace Shtirlitz.Reporter.PingReporter +{ + public class PingProvider : IPingReporterProvider + { + public PingResult Current { get; private set; } + public double Weight + { + get + { + var result = 1; + if (_count > 0) + result = 100 * _currCount / _count; + return result; + } + } + + public PingProvider(string host, int count) + { + _host = host; + _count = count; + _currCount = count; + } + + public bool Next() + { + var result = false; + + if (_currCount > 0) + { + result = SendPing(); + _currCount--; + } + + return result; + } + + private bool SendPing() + { + var result = false; + + using (var ping = new Ping()) + { + var pingResult = ping.Send(_host); + _send++; + if (pingResult != null) + { + if (pingResult.Status == IPStatus.Success) + _receive++; + + Current = new PingResult + { + Host = _host, + Send = _send, + Receive = _receive, + Lost = _lost, + RoundtripTime = pingResult.RoundtripTime + }; + + result = true; + } + else + { + _lost++; + } + } + return result; + } + + private readonly string _host; + private readonly int _count; + private int _currCount; + + private int _send; + private int _receive; + private int _lost; + } +} \ No newline at end of file diff --git a/Shtirlitz.Library/Reporter/PingReporter/PingReporter.cs b/Shtirlitz.Library/Reporter/PingReporter/PingReporter.cs new file mode 100644 index 0000000..e5003de --- /dev/null +++ b/Shtirlitz.Library/Reporter/PingReporter/PingReporter.cs @@ -0,0 +1,33 @@ +using System.IO; +using System.Threading; +using Shtirlitz.Common; + +namespace Shtirlitz.Reporter.PingReporter +{ + public class PingReport : IReporter + { + public double Weight => _provider.Weight; + public string Name => "Ping/Trace reporter"; + + public PingReport(IPingReporterProvider provider) + { + _provider = provider; + } + + public void Report(string rootPath, CancellationToken cancellationToken, SimpleProgressCallback progressCallback = null) + { + while (_provider.Next()) + { + if (cancellationToken.IsCancellationRequested) + break; + + var message = $"Host {_provider.Current.Host} Send {_provider.Current.Send} Receive {_provider.Current.Receive} Lost {_provider.Current.Lost}\r\n"; + File.AppendAllText(rootPath, message); + + progressCallback?.Invoke(Weight); + } + } + + private readonly IPingReporterProvider _provider; + } +} \ No newline at end of file diff --git a/Shtirlitz.Library/Reporter/PingReporter/PingResult.cs b/Shtirlitz.Library/Reporter/PingReporter/PingResult.cs new file mode 100644 index 0000000..7f425f6 --- /dev/null +++ b/Shtirlitz.Library/Reporter/PingReporter/PingResult.cs @@ -0,0 +1,12 @@ + +namespace Shtirlitz.Reporter.PingReporter +{ + public class PingResult + { + public string Host { get; set; } + public int Send { get; set; } + public int Receive { get; set; } + public int Lost { get; set; } + public long RoundtripTime { get; set; } + } +} \ No newline at end of file diff --git a/Shtirlitz.Library/Reporter/PingReporter/TraceProvider.cs b/Shtirlitz.Library/Reporter/PingReporter/TraceProvider.cs new file mode 100644 index 0000000..401d933 --- /dev/null +++ b/Shtirlitz.Library/Reporter/PingReporter/TraceProvider.cs @@ -0,0 +1,143 @@ +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; + +namespace Shtirlitz.Reporter.PingReporter +{ + public class TraceProvider : IPingReporterProvider + { + public PingResult Current { get; private set; } + public double Weight + { + get + { + var result = 1; + if (_count > 0) + result = 100 * _currCount / _count; + return result; + } + } + + public TraceProvider(string host, int jumps, int timeout, int count) + { + _host = host; + _jumps = jumps; + _timeout = timeout; + _count = count; + _currCount = count; + + _stat = new Dictionary(); + _lost = new Dictionary(); + } + + public bool Next() + { + var result = false; + + if (_currCount > 0) + { + var isfinal = SendPing(); + + _currJumps++; + if (_currJumps == _jumps + || isfinal) + { + _currJumps = 0; + _currCount--; + } + + result = true; + } + + return result; + } + + private readonly string _host; + private readonly int _jumps; + private readonly int _timeout; + private readonly Dictionary _stat; + private readonly Dictionary _lost; + private readonly int _count; + private int _currCount; + + private int _currJumps; + + private bool SendPing() + { + var result = false; + + ResetCurrent(); + using (var ping = new Ping()) + { + var pingResult = ping.Send(_host, _timeout, new byte[0], new PingOptions() {Ttl = _currJumps + 1}); + if (pingResult?.Status == IPStatus.Success + || pingResult?.Status == IPStatus.TtlExpired) + { + var curr = UpdateStat(pingResult); + UpdateCurrent(curr); + + result = pingResult.Status == IPStatus.Success; + } + else + { + UpdateLost(); + } + } + + return result; + } + + private PingResult UpdateStat(PingReply pingResult) + { + PingResult curr; + if (!_stat.TryGetValue(pingResult.Address, out curr)) + { + curr = new PingResult + { + Host = pingResult.Address.ToString(), + Send = 1, + Receive = 1, + RoundtripTime = pingResult.RoundtripTime + }; + + _stat[pingResult.Address] = curr; + } + else + { + curr.Send++; + curr.Receive++; + } + return curr; + } + + private void UpdateLost() + { + int lost; + if (_lost.TryGetValue(_currJumps, out lost)) + _lost[_currJumps] = lost + 1; + else + _lost[_currJumps] = 1; + } + + private void ResetCurrent() + { + int lost; + if (_lost.TryGetValue(_currJumps, out lost)) + Current = new PingResult { Host = _currJumps.ToString(), Send = lost + 1, Lost = lost + 1 }; + else + Current = new PingResult { Host = _currJumps.ToString(), Send = 1, Lost = 1 }; + } + + private void UpdateCurrent(PingResult source) + { + Current = new PingResult + { + Host = source.Host, + Send = source.Send, + Receive = source.Receive, + Lost = source.Lost, + RoundtripTime = source.RoundtripTime + }; + } + } +} \ No newline at end of file diff --git a/Shtirlitz.Library/Shtirlitz.Library.csproj b/Shtirlitz.Library/Shtirlitz.Library.csproj index a876bfe..0b07c41 100644 --- a/Shtirlitz.Library/Shtirlitz.Library.csproj +++ b/Shtirlitz.Library/Shtirlitz.Library.csproj @@ -33,8 +33,9 @@ 4 - - $(SolutionDir)packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll + + ..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll + True @@ -44,6 +45,11 @@ + + + + + @@ -53,15 +59,15 @@ - - - {813AEDD8-7C91-41F0-A060-F000530168F6} Shtirlitz + + +