EonaCat.Network
EonaCat.Network is a .NET networking library that provides a common set of APIs for building networked applications and services.
The library includes support for:
- TCP client and server communication
- UDP client and server communication
- WebSockets
- An embedded HTTP/HTTPS web server
- HTTP routing, including static and parameterized routes
- QUIC client/server and stream primitives
- IPv4 and IPv6 networking
- TCP SSL/TLS support
- WebSocket extensions, fragmentation and compression support
- Network-related helper and utility classes
Installation
Install the NuGet package:
dotnet add package EonaCat.Network
NuGet:
https://www.nuget.org/packages/EonaCat.Network/
Target Frameworks
The library currently targets:
- .NET Framework 4.8 (
net48) - .NET Standard 2.1
- .NET 6
- .NET 7
- .NET 8
Quick Start
TCP server
using EonaCat.Network;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
var server = new SocketTcpServer(IPAddress.Any, 5000);
server.OnConnect += remote =>
{
Console.WriteLine("Client connected");
};
server.OnReceive += (remote, message) =>
{
Console.WriteLine($"Received: {message}");
};
server.OnDisconnect += remote =>
{
Console.WriteLine("Client disconnected");
};
server.OnError += (exception, message) =>
{
Console.WriteLine(message);
};
await server.StartAsync(CancellationToken.None);
TCP client
using EonaCat.Network;
var client = new SocketTcpClient();
client.OnConnect += remote =>
{
Console.WriteLine("Connected");
};
client.OnReceive += remote =>
{
Console.WriteLine($"Received {remote.Data?.Length ?? 0} bytes");
};
client.OnDisconnect += remote =>
{
Console.WriteLine("Disconnected");
};
client.OnError += (exception, message) =>
{
Console.WriteLine(message);
};
await client.ConnectAsync("127.0.0.1", 5000);
await client.SendAsync(
System.Text.Encoding.UTF8.GetBytes("Hello from EonaCat.Network!"));
UDP server
using EonaCat.Network;
using System.Net;
var server = new SocketUdpServer(IPAddress.Any, 5001);
server.OnReceive += remote =>
{
Console.WriteLine($"Received {remote.Data?.Length ?? 0} bytes");
};
server.OnSend += remote =>
{
Console.WriteLine("UDP packet sent");
};
server.OnError += (exception, message) =>
{
Console.WriteLine(message);
};
await server.StartAsync();
Send a packet:
await server.SendToAsync(
new IPEndPoint(IPAddress.Loopback, 5002),
System.Text.Encoding.UTF8.GetBytes("Hello UDP"));
UDP client
using EonaCat.Network;
using System.Net;
var client = new SocketUdpClient(IPAddress.Loopback, 5001);
client.OnReceive += data =>
{
Console.WriteLine($"Received {data.Length} bytes");
};
client.OnError += (exception, message) =>
{
Console.WriteLine(message);
};
await client.SendTo(
new IPEndPoint(IPAddress.Loopback, 5001),
System.Text.Encoding.UTF8.GetBytes("Hello UDP"));
Embedded Web Server
The library includes an HTTP/HTTPS web server exposed through WebServer (EonaCat.Network.WebServer).
Start a web server
using EonaCat.Network;
var server = new WebServer("localhost", 8080);
await server.StartAsync();
For synchronous startup:
server.Start();
Stop it with:
server.Stop();
Or dispose it:
server.Dispose();
Web server settings
You can configure the server through EonaCatWebserverSettings:
using EonaCat.Network;
var settings = new EonaCatWebserverSettings("localhost", 8080);
settings.IO.MaxRequests = 1024;
settings.IO.StreamBufferSize = 65536;
settings.Debug.Requests = true;
settings.Debug.Responses = true;
settings.Debug.Routing = true;
var server = new WebServer(settings);
await server.StartAsync();
The settings API includes:
- Listening prefixes
- I/O buffer size
- Maximum concurrent requests
- SSL settings
- Default response headers
- Access-control configuration
- Debug logging options
Security note: review the SSL and access-control configuration before exposing a server to an untrusted network. The current settings class allows invalid certificates by default, so production deployments should explicitly configure certificate validation behavior appropriate to the application.
Web server events
The server exposes events for common lifecycle and HTTP operations through server.Events, including:
ConnectionReceivedRequestReceivedRequestDeniedRequestorDisconnectedResponseSentExceptionEncounteredServerStartedServerStoppedServerDisposing
Example:
server.Events.ServerStarted += (_, _) =>
{
Console.WriteLine("Web server started");
};
server.Events.RequestReceived += (_, args) =>
{
Console.WriteLine("HTTP request received");
};
HTTP Routing
EonaCat.Network provides several route types.
Static routes
StaticRouteManager matches an HTTP method and exact path.
var routes = new StaticRouteManager();
routes.Add(
HttpMethod.GET,
"/hello",
async context =>
{
// Build and send the response here.
await Task.CompletedTask;
});
Static routes normalize paths to begin and end with / and use case-insensitive matching.
Useful operations include:
routes.Add(...);
routes.Get(HttpMethod.GET, "/hello");
routes.Exists(HttpMethod.GET, "/hello");
routes.Remove(HttpMethod.GET, "/hello");
Parameter routes
ParameterRouteManager supports URL parameters such as:
GET /api/{version}/users
Example:
var routes = new ParameterRouteManager();
routes.Add(
HttpMethod.GET,
"/api/{version}/users",
async context =>
{
await Task.CompletedTask;
});
The matching operation returns the extracted values:
Dictionary<string, string> values;
ParameterRoute route;
var handler = routes.Match(
HttpMethod.GET,
"/api/v1/users",
out values,
out route);
For the example above, values can contain:
version = v1
WebSockets
The library contains asynchronous WebSocket client and server implementations under the EonaCat.WebSockets namespace.
Supported functionality includes:
- Text messages
- Binary messages
- Streaming binary data
- Sessions
- Broadcasting
- Fragmentation
- Close handling
- Sub-protocol support
- WebSocket extensions
- Per-message compression support
WebSocket client
using EonaCat.WebSockets;
var client = new AsyncWebSocketClient(
new Uri("ws://localhost:8080/"));
await client.ConnectAsync();
await client.SendTextAsync("Hello WebSocket!");
Binary data:
await client.SendBinaryAsync(
System.Text.Encoding.UTF8.GetBytes("Binary message"));
Close the connection:
await client.CloseAsync();
WebSocket server
The server uses AsyncWebSocketServerModule implementations to handle sessions and messages.
A module can override handlers such as:
public override async Task OnSessionStarted(
AsyncWebSocketSession session)
{
await session.SendTextAsync("Welcome!");
}
public override async Task OnSessionTextReceived(
AsyncWebSocketSession session,
string text)
{
await session.SendTextAsync($"Echo: {text}");
}
public override async Task OnSessionBinaryReceived(
AsyncWebSocketSession session,
byte[] data,
int offset,
int count)
{
await Task.CompletedTask;
}
public override async Task OnSessionClosed(
AsyncWebSocketSession session)
{
await base.OnSessionClosed(session);
}
Server instances can send to individual sessions or broadcast to all connected sessions:
await server.SendTextToAsync(sessionKey, "Hello");
await server.BroadcastTextAsync("Message for everyone");
Binary equivalents are also available.
QUIC
EonaCat.Network contains a QUIC implementation with connection and stream abstractions.
The main public types include:
QuicClientQuicServerQuicConnectionQuicStreamStreamType- QUIC packet and frame infrastructure
- QUIC settings and protocol helpers
QUIC client
using EonaCat.Quic;
var client = new QuicClient();
var connection = client.Connect("127.0.0.1", 11000);
var stream = connection.CreateStream(
StreamType.ClientBidirectional);
stream.Send(
System.Text.Encoding.UTF8.GetBytes("Hello QUIC"));
QUIC server
using EonaCat.Quic;
var server = new QuicServer("0.0.0.0", 11000);
server.OnClientConnected += connection =>
{
Console.WriteLine("QUIC client connected");
};
server.Start();
Important: the QUIC implementation is part of this library's own protocol stack. Validate the protocol behavior, interoperability and security characteristics against your application's requirements before using it for production Internet-facing workloads.
NetworkHelper
For simple QUIC scenarios, NetworkHelper provides convenience methods:
using EonaCat.Network;
NetworkHelper.QuicStartServer("0.0.0.0", 11000);
var stream = NetworkHelper.QuicStartClient(
"127.0.0.1",
11000);
NetworkHelper.QuicStopServer();
It also exposes events for:
OnQuicClientConnectedOnQuicStreamOpenedOnQuicStreamDataReceived
The default global encoding is UTF-8:
NetworkHelper.GlobalEncoding = System.Text.Encoding.UTF8;
IPv4 and IPv6
The socket implementations support IPv4 and IPv6 where supported by the underlying .NET socket APIs.
The library also exposes:
public enum IPType : byte
{
IPv4,
IPv6
}
TCP and UDP implementations expose IPv6-related information through their connection/remote information objects.
TCP SSL/TLS
TCP clients and servers can use SSL/TLS.
Client example:
var client = new SocketTcpClient();
await client.ConnectAsync(
"127.0.0.1",
5000,
useSsl: true,
sslOptions: new SslOptions());
The TCP server accepts a certificate and SSL options:
var server = new SocketTcpServer(
"0.0.0.0",
5000,
certificate,
sslOptions);
Always use certificates and TLS settings appropriate for the environment in which the application is deployed.
Dependencies
The package uses several EonaCat and .NET dependencies, including:
- EonaCat.Controls
- EonaCat.Json
- EonaCat.LogStack
- EonaCat.LogSystem
- EonaCat.Matchers
- EonaCat.Versioning
- System.Net.WebSockets
- System.Text.Encodings.Web
These are restored automatically when installing the NuGet package.
License
EonaCat.Network is released under the Apache License 2.0.
See LICENSE for the complete license text.
Copyright © EonaCat (Jeroen Saey).