You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
5.0 KiB
129 lines
5.0 KiB
using ISPChk.Models;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.NetworkInformation;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ISPChk
|
|
{
|
|
public class NetworkTest : INetworkTest
|
|
{
|
|
private ISPChkContext _context;
|
|
|
|
public NetworkTest() {
|
|
_context = CreateDbContext();
|
|
}
|
|
|
|
public async void LoadHostsFromDatabase()
|
|
{
|
|
List<Host> hosts = await _context.Hosts.Include(host => host.PingItems).ToListAsync();
|
|
foreach (Host host in hosts)
|
|
{
|
|
AddHost(host);
|
|
}
|
|
}
|
|
|
|
private ISPChkContext CreateDbContext()
|
|
{
|
|
var optionsBuilder = new DbContextOptionsBuilder<ISPChkContext>();
|
|
optionsBuilder.UseSqlite("Data Source=ispchk.db");
|
|
var ctx = new ISPChkContext(optionsBuilder.Options);
|
|
System.Diagnostics.Debug.WriteLine("NetworkTest instantiated.");
|
|
ctx.Database.EnsureCreated();
|
|
return ctx;
|
|
}
|
|
|
|
private void StartPing(Host host)
|
|
{
|
|
var t = Task.Run(async () => {
|
|
|
|
// Do not use the outer context, not threadsafe?
|
|
var ctx = CreateDbContext();
|
|
var h = await ctx.Hosts.FindAsync(host.HostId);
|
|
ctx.Entry(h).Collection(hst => hst.PingItems).Load();
|
|
|
|
Ping pingSender = new Ping();
|
|
|
|
// Create a buffer of 32 bytes of data to be transmitted.
|
|
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
byte[] buffer = Encoding.ASCII.GetBytes(data);
|
|
|
|
// Wait 10 seconds for a reply.
|
|
int timeout = 3000;
|
|
|
|
// Set options for transmission:
|
|
// The data can go through 64 gateways or routers
|
|
// before it is destroyed, and the data packet
|
|
// cannot be fragmented.
|
|
PingOptions options = new PingOptions(64, true);
|
|
|
|
System.Diagnostics.Debug.WriteLine("Pinging " + host.Name);
|
|
|
|
while (true)
|
|
{
|
|
int numPings = 5;
|
|
long min = timeout + 1;
|
|
long max = 0;
|
|
long avg = 0;
|
|
int successes = 0;
|
|
int failures = 0;
|
|
for (var i = 0; i < numPings; ++i)
|
|
{
|
|
// Send the request.
|
|
PingReply reply = pingSender.Send(host.HostName, timeout, buffer, options);
|
|
|
|
if (reply.Status == IPStatus.Success)
|
|
{
|
|
successes++;
|
|
//System.Diagnostics.Debug.WriteLine("Reply from " + reply.Address.ToString() +
|
|
// ": bytes=" + reply.Buffer.Length +
|
|
// " time=" + reply.RoundtripTime + "ms");
|
|
avg += reply.RoundtripTime;
|
|
if (reply.RoundtripTime < min)
|
|
{
|
|
min = reply.RoundtripTime;
|
|
}
|
|
if (reply.RoundtripTime > max)
|
|
{
|
|
max = reply.RoundtripTime;
|
|
}
|
|
//System.Diagnostics.Debug.WriteLine("Time to live: {0}", reply.Options.Ttl);
|
|
//System.Diagnostics.Debug.WriteLine("Don't fragment: {0}", reply.Options.DontFragment);
|
|
}
|
|
else
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(reply.Status);
|
|
failures++;
|
|
}
|
|
Thread.Sleep(500);
|
|
}
|
|
if(successes > 0)
|
|
avg = avg / successes;
|
|
// FIXME: This is dirty but I don't want the graph to explode
|
|
if (min > timeout)
|
|
min = 0;
|
|
System.Diagnostics.Debug.WriteLine(h.HostName+": "+"min:" + min + " max:" + max + " avg:" + avg);
|
|
PingItem pi = new PingItem { Date = DateTimeOffset.UtcNow, Min = min, Max = max, Avg = avg, Failures = failures };
|
|
h.PingItems.Add(pi);
|
|
ctx.SaveChanges();
|
|
// Throttle if everything is ok
|
|
if(successes == numPings)
|
|
Thread.Sleep(5000);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void AddHost(Host host)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("Host added!");
|
|
if (host.PingItems == null)
|
|
host = _context.Hosts.Include(host => host.PingItems).Where(h => h.HostId == host.HostId).Single();
|
|
if(host.Ping)
|
|
StartPing(host);
|
|
}
|
|
}
|
|
}
|
|
|