- 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)
{
if (string.IsNullOrWhiteSpace(filePath))
{
fileInfo = null;
errorMessage = "Path is empty!";
return false;
}
string fullPath = Path.GetFullPath(filePath);
if (!File.Exists(fullPath))
@@ -40,9 +40,10 @@ internal class HostsManager
SaveHosts();
}
public void RemoveInactiveHosts()
public int CheckHostsActivity()
{
List<NetworkSocket> hostsToRemove = new List<NetworkSocket>();
int activeHostsCount = 0;
foreach (NetworkSocket host in hosts)
{
ConsoleExt.Write($"{host.IPAddress}:{host.Port} > ???", ConsoleColor.DarkYellow);
@@ -55,16 +56,24 @@ internal class HostsManager
if (tcpClient.Connected)
{
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Active", ConsoleColor.Green);
host.LastActive = DateTime.Now;
activeHostsCount++;
}
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);
}
}
catch
{
hostsToRemove.Add(host);
if (DateTime.Now - host.LastActive >= new TimeSpan(24, 0, 0))
{
hostsToRemove.Add(host);
}
Console.CursorLeft = 0;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Inactive", ConsoleColor.Red);
}
@@ -76,6 +85,7 @@ internal class HostsManager
}
SaveHosts();
return activeHostsCount;
}
public List<NetworkSocket> ToList()
@@ -83,7 +93,7 @@ internal class HostsManager
return hosts.ToList();
}
private void SaveHosts()
public void SaveHosts()
{
File.WriteAllText(Program.HostsFilePath, JsonSerializer.Serialize(hosts));
}
@@ -12,7 +12,7 @@ namespace HyperbolicDownloader.Networking
public bool IsListening { get; private set; } = false;
private TcpListener? tcpListener;
private FilesManager filesManager;
private readonly FilesManager filesManager;
private readonly Dictionary<string, (Type type, Delegate method)> events = new();
public NetworkClient(FilesManager filesManager)
@@ -107,7 +107,7 @@ namespace HyperbolicDownloader.Networking
NetworkStream nwStream = client.GetStream();
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);
@@ -4,10 +4,12 @@ internal class NetworkSocket
{
public string IPAddress { 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;
Port = port;
LastActive = lastActive;
}
}
+33 -17
View File
@@ -20,8 +20,21 @@ internal class Program
public const string HostsFilePath = "Hosts.json";
public const string FilesInfoPath = "Files.json";
private static int publicPort;
private static readonly int privatePort = 3055;
public static int PublicPort { get; private set; }
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 Mapping? portMapping;
private static readonly HostsManager hostsManager = new();
@@ -50,7 +63,7 @@ internal class Program
_ = await OpenPorts();
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...");
@@ -60,7 +73,7 @@ internal class Program
networkClient.ListenTo<List<NetworkSocket>>("DiscoverAnswer", DiscoverAnswer);
networkClient.ListenTo<string>("Message", ReciveMessage);
networkClient.ListenTo<string>("HasFile", HasFile);
networkClient.StartListening(privatePort);
networkClient.StartListening(PrivatePort);
}
catch (SocketException ex)
{
@@ -71,23 +84,25 @@ internal class Program
BroadcastClient broadcastClient = new BroadcastClient();
Console.WriteLine("Running local discovery routine...");
BroadcastClient.Send(BroadcastPort, privatePort.ToString());
BroadcastClient.Send(BroadcastPort, PrivatePort.ToString());
await Task.Delay(5000);
int activeHostsCount = 0;
if (hostsManager.Count > 0)
{
Console.WriteLine("Checking if hosts are active...");
hostsManager.RemoveInactiveHosts();
activeHostsCount = hostsManager.CheckHostsActivity();
}
if (hostsManager.Count == 0)
if (activeHostsCount == 0)
{
hostsManager.AddRange(await Setup.ConfigureHost());
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...");
broadcastClient.StartListening(BroadcastPort);
broadcastClient.OnBroadcastRecived += BroadcastClient_OnBroadcastRecived;
@@ -116,7 +131,7 @@ internal class Program
if (success)
{
hostsManager.Add(new NetworkSocket(recivedEventArgs.IPEndPoint.Address.ToString(), remotePort));
hostsManager.Add(new NetworkSocket(recivedEventArgs.IPEndPoint.Address.ToString(), remotePort, DateTime.Now));
try
{
await NetworkClient.SendAsync(recivedEventArgs.IPEndPoint.Address, remotePort, "DiscoverAnswer", hostsToSend);
@@ -170,7 +185,7 @@ internal class Program
{
try
{
publicPort = random.Next(1000, 6000);
PublicPort = random.Next(1000, 6000);
NatDiscoverer? discoverer = new NatDiscoverer();
device = await discoverer.DiscoverDeviceAsync();
@@ -178,11 +193,11 @@ internal class Program
IPAddress? ip = await device.GetExternalIPAsync();
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);
ConsoleExt.WriteLine($"The public port is: {publicPort}", ConsoleColor.Green);
ConsoleExt.WriteLine($"The public port is: {PublicPort}", ConsoleColor.Green);
return true;
}
catch (NatDeviceNotFoundException)
@@ -192,7 +207,7 @@ internal class Program
}
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;
}
}
@@ -226,11 +241,12 @@ internal class Program
private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e)
{
ClosePorts();
hostsManager.SaveHosts();
}
public static NetworkSocket? GetLocalSocket()
{
int port = publicPort;
int port = PublicPort;
string? ipAddress = null;
if (device is not null)
@@ -241,7 +257,7 @@ internal class Program
if (ipAddress is null || ipAddress == "0.0.0.0")
{
ipAddress = NetworkUtilities.GetIP4Adress()?.ToString();
port = privatePort;
port = PrivatePort;
}
if (ipAddress is null)
@@ -249,6 +265,6 @@ internal class Program
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)
{
this.hostsManager = hostsManager;
commander.Register((_) => Console.Clear(), "clear");
commander.Register(Exit, "exit");
commander.Register((_) => Console.Clear(), "clear", "cls");
commander.Register(Exit, "exit", "quit");
commander.Register(ShowInfo, "info", "inf");
commander.Register(GetFile, "get");
Command addCommand = commander.Register(AddFile, "add");
addCommand.Register(AddHost, "host");
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;
}
@@ -39,6 +45,7 @@ internal class InputHandler
{
while (!exit)
{
Console.WriteLine();
Console.Write("> ");
Console.CursorVisible = true;
@@ -75,7 +82,7 @@ internal class InputHandler
try
{
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);
if (recivedHosts is not null)
@@ -134,10 +141,38 @@ internal class InputHandler
Console.WriteLine($"Hash: {fileInfo.Hash}");
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 _)
{
hostsManager.SaveHosts();
exit = true;
}
@@ -177,10 +212,13 @@ internal class InputHandler
}
else if (!sendTask.Result)
{
host.LastActive = DateTime.Now;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Does not have the requested file", ConsoleColor.Red);
continue;
}
host.LastActive = DateTime.Now;
ConsoleExt.WriteLine($"{host.IPAddress}:{host.Port} > Has the requested file", ConsoleColor.Green);
Console.WriteLine("Requesting file...");
@@ -256,12 +294,12 @@ internal class InputHandler
unitsPerSecond = (unitsPerSecond + bytesInOneSecond) / 2;
if (unitsPerSecond > 125000)
{
unitsPerSecond = unitsPerSecond / 125000;
unitsPerSecond /= 125000;
unit = "Mb";
}
else
{
unitsPerSecond = unitsPerSecond / 125;
unitsPerSecond /= 125;
unit = "Kb";
}
bytesInOneSecond = 0;
@@ -291,6 +329,7 @@ internal class InputHandler
Console.WriteLine($"File saved at: {Path.GetFullPath($"./Downloads/{fileName}")}");
ConsoleExt.WriteLine("Done", ConsoleColor.Green);
stopWatch.Stop();
hostsManager.SaveHosts();
return;
}
else
@@ -299,5 +338,6 @@ internal class InputHandler
}
}
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
{
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);
if (recivedHosts is not null)