Convert TCP networking to sync and binary, add DHCP and IP stack init on boot

This commit is contained in:
Stone_Red
2026-06-18 23:54:23 +02:00
parent 79bc87f5c7
commit ba5d670d1a
8 changed files with 345 additions and 143 deletions
+21 -51
View File
@@ -1,19 +1,17 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
using System.Text.Json;
namespace RemSox.Networking;
public class TcpRpcServer(IPacketCrypto? crypto = null) : TcpRpcBase(crypto)
{
// Fix: Using ConcurrentDictionary to prevent collection errors during structural additions/prunings
private readonly ConcurrentDictionary<TcpConnection, byte> connections = new();
private readonly ConcurrentDictionary<string, byte> activeEndpoints = new();
private TcpListener? listener;
private CancellationTokenSource? cts;
public async Task StartAsync(int port, CancellationToken token = default)
public void StartAsync(int port, CancellationToken token = default)
{
cts = CancellationTokenSource.CreateLinkedTokenSource(token);
@@ -24,17 +22,25 @@ public class TcpRpcServer(IPacketCrypto? crypto = null) : TcpRpcBase(crypto)
{
while (!cts.IsCancellationRequested)
{
TcpClient client = await listener.AcceptTcpClientAsync(cts.Token);
TcpClient client = listener.AcceptTcpClient();
string ep = client.Client.RemoteEndPoint?.ToString() ?? "";
if (!activeEndpoints.TryAdd(ep, 0))
{
client.Close();
Thread.Sleep(10);
continue;
}
Console.WriteLine($"Client connected: {ep}");
TcpConnection conn = new(client);
_ = connections.TryAdd(conn, 0);
_ = HandleConnection(conn, cts.Token);
_ = Task.Run(() => HandleConnection(conn, cts.Token));
}
}
catch (OperationCanceledException)
{
// Expected shutdown scenario
}
}
@@ -51,62 +57,26 @@ public class TcpRpcServer(IPacketCrypto? crypto = null) : TcpRpcBase(crypto)
connections.Clear();
}
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Handled via library constraints")]
public void RespondTo<TReq, TRes>(string type, Func<TReq, Task<TRes>> handler)
public void SendRawToAll(string type, byte[] payload)
{
handlers[type] = async (conn, msg) =>
{
TReq req = JsonSerializer.Deserialize<TReq>(msg.Payload)!;
TRes res = await handler(req);
await SendRaw(conn, new TcpMessage
{
Type = type,
RequestId = msg.RequestId,
Payload = JsonSerializer.SerializeToUtf8Bytes(res)
});
};
}
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Handled via library constraints")]
public Task SendToAll<T>(string type, T data)
{
byte[] payloadBytes = JsonSerializer.SerializeToUtf8Bytes(data);
List<Task> sendTasks = [];
foreach (TcpConnection conn in connections.Keys)
{
sendTasks.Add(SendRaw(conn, new TcpMessage
{
Type = type,
RequestId = Guid.NewGuid().ToString(),
Payload = payloadBytes
}));
}
return Task.WhenAll(sendTasks);
}
/// <summary> Broadcasts raw binary payload to all connected clients. </summary>
public Task SendRawToAll(string type, byte[] payload)
{
List<Task> sendTasks = [];
foreach (TcpConnection conn in connections.Keys)
{
sendTasks.Add(SendRaw(conn, new TcpMessage
SendRaw(conn, new TcpMessage
{
Type = type,
RequestId = Guid.NewGuid().ToString(),
Payload = payload
}));
});
}
return Task.WhenAll(sendTasks);
}
protected override void OnConnectionClosed(TcpConnection conn)
{
_ = connections.TryRemove(conn, out _);
string ep = conn.Client.Client.RemoteEndPoint?.ToString() ?? "";
_ = activeEndpoints.TryRemove(ep, out _);
Console.WriteLine($"Client disconnected: {ep}");
}
}