- Optimize downloading process

- Add expiration time to inactive hosts
This commit is contained in:
Stone_Red
2022-01-27 21:40:29 +01:00
parent f2c01d2a38
commit 2df780709f
7 changed files with 107 additions and 32 deletions
@@ -8,6 +8,13 @@ internal class FilesManager
public bool TryAdd(string filePath, out HyperFileInfo? fileInfo, out string? errorMessage) public bool TryAdd(string filePath, out HyperFileInfo? fileInfo, out string? errorMessage)
{ {
if (string.IsNullOrWhiteSpace(filePath))
{
fileInfo = null;
errorMessage = "Path is empty!";
return false;
}
string fullPath = Path.GetFullPath(filePath); string fullPath = Path.GetFullPath(filePath);
if (!File.Exists(fullPath)) if (!File.Exists(fullPath))
@@ -40,9 +40,10 @@ internal class HostsManager
SaveHosts(); SaveHosts();
} }
public void RemoveInactiveHosts() public int CheckHostsActivity()
{ {
List<NetworkSocket> hostsToRemove = new List<NetworkSocket>(); List<NetworkSocket> hostsToRemove = new List<NetworkSocket>();
int activeHostsCount = 0;
foreach (NetworkSocket host in hosts) foreach (NetworkSocket host in hosts)
{ {
ConsoleExt.Write($"{host.IPAddress}:{host.Port} > ???", ConsoleColor.DarkYellow); ConsoleExt.Write($"{host.IPAddress}:{host.Port} > ???", ConsoleColor.DarkYellow);
@@ -55,16 +56,24 @@ internal class HostsManager
if (tcpClient.Connected) if (tcpClient.Connected)
{ {
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Active", ConsoleColor.Green); ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Active", ConsoleColor.Green);
host.LastActive = DateTime.Now;
activeHostsCount++;
} }
else else
{ {
hostsToRemove.Add(host); if (DateTime.Now - host.LastActive >= new TimeSpan(24, 0, 0))
{
hostsToRemove.Add(host);
}
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Inactive", ConsoleColor.Red); ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Inactive", ConsoleColor.Red);
} }
} }
catch catch
{ {
hostsToRemove.Add(host); if (DateTime.Now - host.LastActive >= new TimeSpan(24, 0, 0))
{
hostsToRemove.Add(host);
}
Console.CursorLeft = 0; Console.CursorLeft = 0;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Inactive", ConsoleColor.Red); ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Inactive", ConsoleColor.Red);
} }
@@ -76,6 +85,7 @@ internal class HostsManager
} }
SaveHosts(); SaveHosts();
return activeHostsCount;
} }
public List<NetworkSocket> ToList() public List<NetworkSocket> ToList()
@@ -83,7 +93,7 @@ internal class HostsManager
return hosts.ToList(); return hosts.ToList();
} }
private void SaveHosts() public void SaveHosts()
{ {
File.WriteAllText(Program.HostsFilePath, JsonSerializer.Serialize(hosts)); File.WriteAllText(Program.HostsFilePath, JsonSerializer.Serialize(hosts));
} }
@@ -12,7 +12,7 @@ namespace HyperbolicDownloader.Networking
public bool IsListening { get; private set; } = false; public bool IsListening { get; private set; } = false;
private TcpListener? tcpListener; private TcpListener? tcpListener;
private FilesManager filesManager; private readonly FilesManager filesManager;
private readonly Dictionary<string, (Type type, Delegate method)> events = new(); private readonly Dictionary<string, (Type type, Delegate method)> events = new();
public NetworkClient(FilesManager filesManager) public NetworkClient(FilesManager filesManager)
@@ -107,7 +107,7 @@ namespace HyperbolicDownloader.Networking
NetworkStream nwStream = client.GetStream(); NetworkStream nwStream = client.GetStream();
byte[] buffer = new byte[client.ReceiveBufferSize]; byte[] buffer = new byte[client.ReceiveBufferSize];
int bytesRead = await nwStream.ReadAsync(buffer, 0, client.ReceiveBufferSize); int bytesRead = await nwStream.ReadAsync(buffer.AsMemory(0, client.ReceiveBufferSize));
string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead); string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
@@ -4,10 +4,12 @@ internal class NetworkSocket
{ {
public string IPAddress { get; set; } public string IPAddress { get; set; }
public int Port { get; set; } public int Port { get; set; }
public DateTime LastActive { get; set; }
public NetworkSocket(string ipAddress, int port) public NetworkSocket(string ipAddress, int port, DateTime lastActive)
{ {
IPAddress = ipAddress; IPAddress = ipAddress;
Port = port; Port = port;
LastActive = lastActive;
} }
} }
+33 -17
View File
@@ -20,8 +20,21 @@ internal class Program
public const string HostsFilePath = "Hosts.json"; public const string HostsFilePath = "Hosts.json";
public const string FilesInfoPath = "Files.json"; public const string FilesInfoPath = "Files.json";
private static int publicPort; public static int PublicPort { get; private set; }
private static readonly int privatePort = 3055; public static int PrivatePort { get; } = 3055;
public static IPAddress? PublicIpAddress
{
get
{
if (device is not null)
{
return device.GetExternalIPAsync().GetAwaiter().GetResult();
}
return null;
}
}
private static NatDevice? device; private static NatDevice? device;
private static Mapping? portMapping; private static Mapping? portMapping;
private static readonly HostsManager hostsManager = new(); private static readonly HostsManager hostsManager = new();
@@ -50,7 +63,7 @@ internal class Program
_ = await OpenPorts(); _ = await OpenPorts();
ConsoleExt.WriteLine($"The private IP Address is: {NetworkUtilities.GetIP4Adress()} ", ConsoleColor.Green); ConsoleExt.WriteLine($"The private IP Address is: {NetworkUtilities.GetIP4Adress()} ", ConsoleColor.Green);
ConsoleExt.WriteLine($"The private port is: {privatePort}", ConsoleColor.Green); ConsoleExt.WriteLine($"The private port is: {PrivatePort}", ConsoleColor.Green);
Console.WriteLine("Starting TCP listener..."); Console.WriteLine("Starting TCP listener...");
@@ -60,7 +73,7 @@ internal class Program
networkClient.ListenTo<List<NetworkSocket>>("DiscoverAnswer", DiscoverAnswer); networkClient.ListenTo<List<NetworkSocket>>("DiscoverAnswer", DiscoverAnswer);
networkClient.ListenTo<string>("Message", ReciveMessage); networkClient.ListenTo<string>("Message", ReciveMessage);
networkClient.ListenTo<string>("HasFile", HasFile); networkClient.ListenTo<string>("HasFile", HasFile);
networkClient.StartListening(privatePort); networkClient.StartListening(PrivatePort);
} }
catch (SocketException ex) catch (SocketException ex)
{ {
@@ -71,23 +84,25 @@ internal class Program
BroadcastClient broadcastClient = new BroadcastClient(); BroadcastClient broadcastClient = new BroadcastClient();
Console.WriteLine("Running local discovery routine..."); Console.WriteLine("Running local discovery routine...");
BroadcastClient.Send(BroadcastPort, privatePort.ToString()); BroadcastClient.Send(BroadcastPort, PrivatePort.ToString());
await Task.Delay(5000); await Task.Delay(5000);
int activeHostsCount = 0;
if (hostsManager.Count > 0) if (hostsManager.Count > 0)
{ {
Console.WriteLine("Checking if hosts are active..."); Console.WriteLine("Checking if hosts are active...");
hostsManager.RemoveInactiveHosts(); activeHostsCount = hostsManager.CheckHostsActivity();
} }
if (hostsManager.Count == 0) if (activeHostsCount == 0)
{ {
hostsManager.AddRange(await Setup.ConfigureHost()); hostsManager.AddRange(await Setup.ConfigureHost());
Console.WriteLine("Checking if hosts are active..."); Console.WriteLine("Checking if hosts are active...");
hostsManager.RemoveInactiveHosts(); activeHostsCount = hostsManager.CheckHostsActivity();
} }
Console.WriteLine($"{hostsManager.Count} active host(s)."); Console.WriteLine($"{hostsManager.Count} known host(s).");
Console.WriteLine($"{activeHostsCount} active host(s).");
Console.WriteLine("Starting broadcast listener..."); Console.WriteLine("Starting broadcast listener...");
broadcastClient.StartListening(BroadcastPort); broadcastClient.StartListening(BroadcastPort);
broadcastClient.OnBroadcastRecived += BroadcastClient_OnBroadcastRecived; broadcastClient.OnBroadcastRecived += BroadcastClient_OnBroadcastRecived;
@@ -116,7 +131,7 @@ internal class Program
if (success) if (success)
{ {
hostsManager.Add(new NetworkSocket(recivedEventArgs.IPEndPoint.Address.ToString(), remotePort)); hostsManager.Add(new NetworkSocket(recivedEventArgs.IPEndPoint.Address.ToString(), remotePort, DateTime.Now));
try try
{ {
await NetworkClient.SendAsync(recivedEventArgs.IPEndPoint.Address, remotePort, "DiscoverAnswer", hostsToSend); await NetworkClient.SendAsync(recivedEventArgs.IPEndPoint.Address, remotePort, "DiscoverAnswer", hostsToSend);
@@ -170,7 +185,7 @@ internal class Program
{ {
try try
{ {
publicPort = random.Next(1000, 6000); PublicPort = random.Next(1000, 6000);
NatDiscoverer? discoverer = new NatDiscoverer(); NatDiscoverer? discoverer = new NatDiscoverer();
device = await discoverer.DiscoverDeviceAsync(); device = await discoverer.DiscoverDeviceAsync();
@@ -178,11 +193,11 @@ internal class Program
IPAddress? ip = await device.GetExternalIPAsync(); IPAddress? ip = await device.GetExternalIPAsync();
ConsoleExt.WriteLine($"The public IP Address is: {ip} ", ConsoleColor.Green); ConsoleExt.WriteLine($"The public IP Address is: {ip} ", ConsoleColor.Green);
portMapping = new Mapping(Protocol.Tcp, privatePort, publicPort, "HyperbolicDowloader"); portMapping = new Mapping(Protocol.Tcp, PrivatePort, PublicPort, "HyperbolicDowloader");
await device.CreatePortMapAsync(portMapping); await device.CreatePortMapAsync(portMapping);
ConsoleExt.WriteLine($"The public port is: {publicPort}", ConsoleColor.Green); ConsoleExt.WriteLine($"The public port is: {PublicPort}", ConsoleColor.Green);
return true; return true;
} }
catch (NatDeviceNotFoundException) catch (NatDeviceNotFoundException)
@@ -192,7 +207,7 @@ internal class Program
} }
catch (MappingException ex) catch (MappingException ex)
{ {
ConsoleExt.WriteLine($"An error occurred while mapping the private port ({privatePort}) to the public port ({publicPort})! Error message: {ex.Message}", ConsoleColor.Red); ConsoleExt.WriteLine($"An error occurred while mapping the private port ({PrivatePort}) to the public port ({PublicPort})! Error message: {ex.Message}", ConsoleColor.Red);
return false; return false;
} }
} }
@@ -226,11 +241,12 @@ internal class Program
private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e) private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e)
{ {
ClosePorts(); ClosePorts();
hostsManager.SaveHosts();
} }
public static NetworkSocket? GetLocalSocket() public static NetworkSocket? GetLocalSocket()
{ {
int port = publicPort; int port = PublicPort;
string? ipAddress = null; string? ipAddress = null;
if (device is not null) if (device is not null)
@@ -241,7 +257,7 @@ internal class Program
if (ipAddress is null || ipAddress == "0.0.0.0") if (ipAddress is null || ipAddress == "0.0.0.0")
{ {
ipAddress = NetworkUtilities.GetIP4Adress()?.ToString(); ipAddress = NetworkUtilities.GetIP4Adress()?.ToString();
port = privatePort; port = PrivatePort;
} }
if (ipAddress is null) if (ipAddress is null)
@@ -249,6 +265,6 @@ internal class Program
return null; return null;
} }
return new NetworkSocket(ipAddress, port); return new NetworkSocket(ipAddress, port, DateTime.Now);
} }
} }
@@ -23,14 +23,20 @@ internal class InputHandler
public InputHandler(HostsManager hostsManager, FilesManager filesManager) public InputHandler(HostsManager hostsManager, FilesManager filesManager)
{ {
this.hostsManager = hostsManager; this.hostsManager = hostsManager;
commander.Register((_) => Console.Clear(), "clear"); commander.Register((_) => Console.Clear(), "clear", "cls");
commander.Register(Exit, "exit"); commander.Register(Exit, "exit", "quit");
commander.Register(ShowInfo, "info", "inf");
commander.Register(GetFile, "get"); commander.Register(GetFile, "get");
Command addCommand = commander.Register(AddFile, "add"); Command addCommand = commander.Register(AddFile, "add");
addCommand.Register(AddHost, "host"); addCommand.Register(AddHost, "host");
addCommand.Register(AddFile, "file"); addCommand.Register(AddFile, "file");
commander.Register(RemoveFile, "remove");
commander.Register(ListFiles, "list"); commander.Register(RemoveFile, "remove", "rm");
Command listCommand = commander.Register(ListFiles, "list", "ls");
listCommand.Register(ListFiles, "files");
listCommand.Register(ListHosts, "hosts");
this.filesManager = filesManager; this.filesManager = filesManager;
} }
@@ -39,6 +45,7 @@ internal class InputHandler
{ {
while (!exit) while (!exit)
{ {
Console.WriteLine();
Console.Write("> "); Console.Write("> ");
Console.CursorVisible = true; Console.CursorVisible = true;
@@ -75,7 +82,7 @@ internal class InputHandler
try try
{ {
Console.WriteLine("Waiting for response..."); Console.WriteLine("Waiting for response...");
NetworkSocket? localSocket = Program.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0); NetworkSocket? localSocket = Program.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0, DateTime.MinValue);
List<NetworkSocket>? recivedHosts = NetworkClient.Send<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket); List<NetworkSocket>? recivedHosts = NetworkClient.Send<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket);
if (recivedHosts is not null) if (recivedHosts is not null)
@@ -134,10 +141,38 @@ internal class InputHandler
Console.WriteLine($"Hash: {fileInfo.Hash}"); Console.WriteLine($"Hash: {fileInfo.Hash}");
Console.WriteLine(); Console.WriteLine();
} }
Console.CursorTop--;
}
private void ListHosts(string _)
{
int index = 0;
foreach (NetworkSocket host in hostsManager.ToList())
{
index++;
Console.WriteLine($"{index}) {host.IPAddress}:{host.Port}");
Console.WriteLine($"Last active: {host.LastActive}");
Console.WriteLine();
}
Console.CursorTop--;
}
private void ShowInfo(string _)
{
if (Program.PublicIpAddress is not null)
{
ConsoleExt.WriteLine($"The public IP Address is: {Program.PublicIpAddress}", ConsoleColor.Green);
ConsoleExt.WriteLine($"The public port is: {Program.PublicPort}", ConsoleColor.Green);
Console.WriteLine();
}
ConsoleExt.WriteLine($"The private IP Address is: {NetworkUtilities.GetIP4Adress()}", ConsoleColor.Green);
ConsoleExt.WriteLine($"The private port is: {Program.PrivatePort}", ConsoleColor.Green);
} }
private void Exit(string _) private void Exit(string _)
{ {
hostsManager.SaveHosts();
exit = true; exit = true;
} }
@@ -177,10 +212,13 @@ internal class InputHandler
} }
else if (!sendTask.Result) else if (!sendTask.Result)
{ {
host.LastActive = DateTime.Now;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Does not have the requested file", ConsoleColor.Red); ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Does not have the requested file", ConsoleColor.Red);
continue; continue;
} }
host.LastActive = DateTime.Now;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Has the requested file", ConsoleColor.Green); ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Has the requested file", ConsoleColor.Green);
Console.WriteLine("Requesting file..."); Console.WriteLine("Requesting file...");
@@ -256,12 +294,12 @@ internal class InputHandler
unitsPerSecond = (unitsPerSecond + bytesInOneSecond) / 2; unitsPerSecond = (unitsPerSecond + bytesInOneSecond) / 2;
if (unitsPerSecond > 125000) if (unitsPerSecond > 125000)
{ {
unitsPerSecond = unitsPerSecond / 125000; unitsPerSecond /= 125000;
unit = "Mb"; unit = "Mb";
} }
else else
{ {
unitsPerSecond = unitsPerSecond / 125; unitsPerSecond /= 125;
unit = "Kb"; unit = "Kb";
} }
bytesInOneSecond = 0; bytesInOneSecond = 0;
@@ -291,6 +329,7 @@ internal class InputHandler
Console.WriteLine($"File saved at: {Path.GetFullPath($"./Downloads/{fileName}")}"); Console.WriteLine($"File saved at: {Path.GetFullPath($"./Downloads/{fileName}")}");
ConsoleExt.WriteLine("Done", ConsoleColor.Green); ConsoleExt.WriteLine("Done", ConsoleColor.Green);
stopWatch.Stop(); stopWatch.Stop();
hostsManager.SaveHosts();
return; return;
} }
else else
@@ -299,5 +338,6 @@ internal class InputHandler
} }
} }
ConsoleExt.WriteLine("None of the available hosts have the requested file!", ConsoleColor.Red); ConsoleExt.WriteLine("None of the available hosts have the requested file!", ConsoleColor.Red);
hostsManager.SaveHosts();
} }
} }
+1 -1
View File
@@ -33,7 +33,7 @@ internal static class Setup
try try
{ {
Console.WriteLine("Waiting for response..."); Console.WriteLine("Waiting for response...");
NetworkSocket? localSocket = Program.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0); NetworkSocket? localSocket = Program.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0, DateTime.MinValue);
List<NetworkSocket>? recivedHosts = await NetworkClient.SendAsync<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket); List<NetworkSocket>? recivedHosts = await NetworkClient.SendAsync<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket);
if (recivedHosts is not null) if (recivedHosts is not null)