- Order hosts by last active

- Remove `Setup.cs` file
- Add discover command
- Increase request timeout when downloading a file to avoid errors
- Better exception handling for file up/down-loading
This commit is contained in:
Stone_Red
2022-01-28 18:03:46 +01:00
parent b758fa3dd5
commit 996fc7e5a6
6 changed files with 87 additions and 105 deletions
@@ -24,13 +24,11 @@ internal static class FileCompressor
{
byte[] buffer = new byte[chunkSize];
int bytesRead;
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
using (BufferedStream bs = new BufferedStream(fs))
using FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
using BufferedStream bs = new BufferedStream(fs);
while ((bytesRead = bs.Read(buffer, 0, chunkSize)) != 0)
{
while ((bytesRead = bs.Read(buffer, 0, chunkSize)) != 0)
{
yield return buffer;
}
yield return buffer;
}
}
}
@@ -9,7 +9,7 @@ namespace HyperbolicDownloader;
internal class HostsManager
{
private readonly List<NetworkSocket> hosts = new List<NetworkSocket>();
private List<NetworkSocket> hosts = new List<NetworkSocket>();
public int Count => hosts.Count;
public void AddRange(IEnumerable<NetworkSocket> hosts)
@@ -98,6 +98,7 @@ internal class HostsManager
public void SaveHosts()
{
hosts = hosts.OrderByDescending(h => h.LastActive).ToList();
File.WriteAllText(Program.HostsFilePath, JsonSerializer.Serialize(hosts));
}
}
@@ -1,5 +1,6 @@
using HyperbolicDownloader.FileProcessing;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
@@ -155,44 +156,51 @@ namespace HyperbolicDownloader.Networking
private async Task Upload(TcpClient client, string hash)
{
byte[] bytesToSend;
hash = hash.Trim();
NetworkStream nwStream = client.GetStream();
client.SendBufferSize = 64000;
if (filesManager.TryGet(hash, out HyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath))
try
{
if (hash != await FileValidator.CalculateHashAsync(hyperFileInfo.FilePath))
byte[] bytesToSend;
hash = hash.Trim();
NetworkStream nwStream = client.GetStream();
client.SendBufferSize = 64000;
if (filesManager.TryGet(hash, out HyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath))
{
bytesToSend = Encoding.ASCII.GetBytes("Hash does not match!");
await nwStream.WriteAsync(bytesToSend);
return;
}
//string compressedFilePath = $"{hash + DateTime.Now.Millisecond}.temp";
//FileCompressor.CompressFile(hyperFileInfo.FilePath, compressedFilePath);
FileInfo compressedFileInfo = new FileInfo(hyperFileInfo.FilePath);
bytesToSend = Encoding.ASCII.GetBytes($"{compressedFileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}");
await nwStream.WriteAsync(bytesToSend);
foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000))
{
if (chunk is not null)
if (hash != await FileValidator.CalculateHashAsync(hyperFileInfo.FilePath))
{
await nwStream.WriteAsync(chunk);
bytesToSend = Encoding.ASCII.GetBytes("Hash does not match!");
await nwStream.WriteAsync(bytesToSend);
return;
}
}
// File.Delete(compressedFilePath);
//string compressedFilePath = $"{hash + DateTime.Now.Millisecond}.temp";
//FileCompressor.CompressFile(hyperFileInfo.FilePath, compressedFilePath);
FileInfo compressedFileInfo = new FileInfo(hyperFileInfo.FilePath);
bytesToSend = Encoding.ASCII.GetBytes($"{compressedFileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}");
await nwStream.WriteAsync(bytesToSend);
foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000))
{
if (chunk is not null)
{
await nwStream.WriteAsync(chunk);
}
}
// File.Delete(compressedFilePath);
}
else
{
bytesToSend = Encoding.ASCII.GetBytes("File not found!");
await nwStream.WriteAsync(bytesToSend);
}
client.Close();
}
else
catch (Exception ex)
{
bytesToSend = Encoding.ASCII.GetBytes("File not found!");
await nwStream.WriteAsync(bytesToSend);
Debug.WriteLine(ex);
}
client.Close();
}
public void StopListening()
+4 -5
View File
@@ -16,7 +16,7 @@ namespace HyperbolicDownloader;
internal class Program
{
private const int BroadcastPort = 2155;
public const int BroadcastPort = 2155;
public const string HostsFilePath = "Hosts.json";
public const string FilesInfoPath = "Files.json";
@@ -85,7 +85,7 @@ internal class Program
Console.WriteLine("Running local discovery routine...");
BroadcastClient.Send(BroadcastPort, PrivatePort.ToString());
await Task.Delay(5000);
await Task.Delay(3000);
int activeHostsCount = 0;
if (hostsManager.Count > 0)
@@ -96,9 +96,8 @@ internal class Program
if (activeHostsCount == 0)
{
hostsManager.AddRange(await Setup.ConfigureHost());
Console.WriteLine("Checking if hosts are active...");
activeHostsCount = hostsManager.CheckHostsActivity();
ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red);
ConsoleExt.WriteLine("Use 'add host xxx.xxx.xxx.xxx:yyyy' to add a new host.", ConsoleColor.Red);
}
Console.WriteLine($"{hostsManager.Count} known host(s).");
@@ -26,6 +26,7 @@ internal class InputHandler
commander.Register((_) => Console.Clear(), "clear", "cls");
commander.Register(Exit, "exit", "quit");
commander.Register(ShowInfo, "info", "inf");
commander.Register(Discover, "discover", "disc");
commander.Register(GetFile, "get");
Command addCommand = commander.Register(AddFile, "add");
@@ -38,7 +39,7 @@ internal class InputHandler
listCommand.Register(ListFiles, "files");
listCommand.Register(ListHosts, "hosts");
commander.Register((_) => hostsManager.CheckHostsActivity(), "status", "check");
commander.Register(CheckActiveHosts, "status", "check");
this.filesManager = filesManager;
}
@@ -101,6 +102,10 @@ internal class InputHandler
{
ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red);
}
catch (IOException ex)
{
ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red);
}
}
else
{
@@ -172,6 +177,26 @@ internal class InputHandler
ConsoleExt.WriteLine($"The private port is: {Program.PrivatePort}", ConsoleColor.Green);
}
private void Discover(string _)
{
Console.WriteLine("Running local discovery routine...");
BroadcastClient.Send(Program.BroadcastPort, Program.PrivatePort.ToString());
Thread.Sleep(3000);
}
private void CheckActiveHosts(string _)
{
int activeHostsCount = hostsManager.CheckHostsActivity();
if (activeHostsCount == 0)
{
ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red);
ConsoleExt.WriteLine("Use 'add host xxx.xxx.xxx.xxx:yyyy' to add a new host.", ConsoleColor.Red);
}
Console.WriteLine($"{hostsManager.Count} known host(s).");
Console.WriteLine($"{activeHostsCount} active host(s).");
}
private void Exit(string _)
{
hostsManager.SaveHosts();
@@ -236,8 +261,19 @@ internal class InputHandler
byte[] bytesToSend = Encoding.ASCII.GetBytes($"Download {hash}");
nwStream.Write(bytesToSend);
nwStream.ReadTimeout = 5000;
int bytesRead = nwStream.Read(buffer, 0, tcpClient.ReceiveBufferSize);
nwStream.ReadTimeout = 30000;
int bytesRead;
try
{
bytesRead = nwStream.Read(buffer, 0, tcpClient.ReceiveBufferSize);
}
catch (IOException)
{
Console.WriteLine();
ConsoleExt.WriteLine("Lost connection to other host!", ConsoleColor.Red);
continue;
}
string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
@@ -1,60 +0,0 @@
using HyperbolicDownloader.Networking;
using Stone_Red_Utilities.ConsoleExtentions;
using System.Net;
using System.Net.Sockets;
namespace HyperbolicDownloader.UserInterface;
internal static class Setup
{
public static async Task<List<NetworkSocket>> ConfigureHost()
{
ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red);
do
{
Console.WriteLine();
Console.CursorVisible = true;
Console.Write("Please enter an IP address manually: ");
string? ipAddressInput = Console.ReadLine();
Console.Write("Please enter an port number manually: ");
string? portInput = Console.ReadLine();
Console.CursorVisible = false;
_ = int.TryParse(portInput, out int port);
if (port < 1000 || port >= 6000)
{
ConsoleExt.WriteLine("Invalid port number!", ConsoleColor.Red);
}
else if (IPAddress.TryParse(ipAddressInput, out IPAddress? ipAddress))
{
try
{
Console.WriteLine("Waiting for response...");
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)
{
ConsoleExt.WriteLine($"Success! Added {recivedHosts.Count} new host(s).", ConsoleColor.Green);
return recivedHosts;
}
else
{
ConsoleExt.WriteLine($"Invalid response!", ConsoleColor.Red);
}
}
catch (SocketException ex)
{
ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red);
}
}
else
{
ConsoleExt.WriteLine("Invalid IP address!", ConsoleColor.Red);
}
} while (true);
}
}