Connection is established correctly now - need to improve content handling

This commit is contained in:
ti_mo
2026-02-21 23:38:28 +01:00
parent 572bcb32c6
commit 1788f33c2f
+97 -37
View File
@@ -1,51 +1,75 @@
using System.Net; using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
namespace DirectoryScanReceiver; namespace DirectoryScanReceiver;
struct Data
{
public string Name;
public int Length;
public string Content;
public override string ToString() => $"Name: {Name}\nLength: {Length}";
}
static class DataExtractor static class DataExtractor
{ {
public static string? ExtractHeader(byte[] data) public static Data Data;
{
int idx = Array.IndexOf(data, (byte)'\n');
return Encoding.UTF8.GetString(data[..idx]);
}
public static byte[] ExtractContent(byte[] data) public static void LoadAndParseData(string data)
{ {
return data[Array.IndexOf(data, (byte)'\n')..]; Data = new Data();
if (data.Length == 0) return;
var s = data.Split('|').ToList();
if(s.Count < 3) return;
Data.Name = s[0];
try { Data.Length = int.Parse(s[1]); }
catch (Exception ex) { Console.WriteLine(ex.Message); }
var sb = new StringBuilder();
foreach (var sub in s[2..]) sb.Append(sub);
var content = sb.ToString();
var length = Math.Min(content.Length, Data.Length);
Data.Content = content[..length];
} }
} }
static class DataHandler static class DataHandler
{ {
const string OutputDir = "./output"; public const string OutputDir = "./output";
public static void Parse(byte[] data) public static void Parse(string data)
{ {
if (data.Length == 0) return; if (data.Length == 0) return;
var header = DataExtractor.ExtractHeader(data); DataExtractor.LoadAndParseData(data);
var content = DataExtractor.ExtractContent(data); var parsed = DataExtractor.Data;
Console.WriteLine(parsed);
if (header is null || content is null) return; if (parsed.Name.Length == 0 || parsed.Length == 0 || parsed.Content.Length == 0) return;
var fi = new FileInfo(header); var newPath = Path.Combine(OutputDir, parsed.Name);
var dir = Path.GetDirectoryName(header) ?? OutputDir; var fi = new FileInfo(newPath);
var dir = Path.GetDirectoryName(newPath) ?? OutputDir;
var di = new DirectoryInfo(dir); var di = new DirectoryInfo(dir);
if (!di.Exists) di.Create(); if (!di.Exists) di.Create();
if (fi.Exists) return; if (fi.Exists) return;
Console.WriteLine($"Writing File: {header}"); Console.WriteLine($"Writing File: {newPath}");
fi.Create().WriteAsync(new ReadOnlyMemory<byte>(content)); fi.Create().Write(Encoding.UTF8.GetBytes(parsed.Content));
} }
} }
class Server internal class Server
{ {
private TcpListener _listener; private readonly TcpListener _listener;
private NetworkStream _stream;
public Server(int port) public Server(int port)
{ {
@@ -53,9 +77,18 @@ class Server
_listener.Start(); _listener.Start();
} }
public static TcpState GetState(TcpClient tcpClient)
{
var foo = IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpConnections()
.SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint));
return foo is not null ? foo.State : TcpState.Unknown;
}
public void Receiver() public void Receiver()
{ {
// var bytes = new byte[134217728]; // 128 MB if(Directory.Exists(DataHandler.OutputDir)) Directory.Delete(DataHandler.OutputDir, true);
while (true) while (true)
{ {
@@ -65,40 +98,67 @@ class Server
var stream = peer.GetStream(); var stream = peer.GetStream();
Console.WriteLine($"Connected to Peer: {peer.Client.RemoteEndPoint}"); Console.WriteLine($"Connected to Peer: {peer.Client.RemoteEndPoint}");
while (peer.Connected) while (GetState(peer) == TcpState.Established)
{ {
var availableBytes = peer.Available; var buffer = "";
if(availableBytes <= 0) continue;
var bytes = new byte[availableBytes];
try try
{ {
var recvCount = stream.Read(bytes); var start = DateTime.Now;
if(recvCount <= 0) continue; while (!buffer.EndsWith("\r\n\r\n"))
} {
catch (Exception ex) if (DateTime.Now.Subtract(start).TotalMilliseconds >= 10000)
{ {
Console.WriteLine(ex.Message); Console.WriteLine("Receive Timeout!");
} break;
}
Console.WriteLine("Received:\n" + BitConverter.ToString(bytes)); var availableBytes = peer.Available;
DataHandler.Parse(bytes); while (availableBytes > 0)
{
var recvBytes = new byte[availableBytes];
var recvCount = stream.Read(recvBytes);
if(recvCount <= 0) continue;
// TODO: for is to heavy
for (var i = 0; i < recvCount; i++) buffer += (char)recvBytes[i];
availableBytes -= recvCount;
}
}
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
if(buffer.Length == 0) continue;
foreach (var b in buffer.Split("\r\n\r\n"))
{
Console.WriteLine($"Received {b.Length} bytes");
DataHandler.Parse(b);
}
} }
Console.WriteLine("Disconnected from Peer!"); Console.WriteLine("Disconnected from Peer!");
} }
} }
} }
public class Program public static class Program
{ {
public static void Main() public static void Main()
{ {
var server = new Server(7156);
Console.WriteLine("Started Server!");
while (true) while (true)
{ {
var server = new Server(7156);
Console.WriteLine("Started Server!");
Console.WriteLine("Waiting for data!"); Console.WriteLine("Waiting for data!");
server.Receiver(); try
{
server.Receiver();
}
catch (Exception ex)
{
Console.WriteLine("Receiver crashed!");
Console.WriteLine(ex.Message);
}
} }
} }
} }