Giraffe.Net 1.0.0

dotnet add package Giraffe.Net --version 1.0.0
                    
NuGet\Install-Package Giraffe.Net -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Giraffe.Net" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Giraffe.Net" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Giraffe.Net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Giraffe.Net --version 1.0.0
                    
#r "nuget: Giraffe.Net, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Giraffe.Net@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Giraffe.Net&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Giraffe.Net&version=1.0.0
                    
Install as a Cake Tool

Giraffe.Net

A low-level .NET networking library that gives you fine-grained control over the bytes sent over the network. Built for applications where data usage must be minimal — staying under a data cap, running over metered connections, or operating on bandwidth-constrained hardware.

NuGet License: MIT


Features

  • Compact 8-byte wire header — magic byte, version, 16-bit message type, 32-bit payload length. Minimal overhead on every message.
  • Per-message protocol selection — choose TCP or UDP at the point of each SendAsync call.
  • Generic message types — define your own enum : ushort for message identifiers; the library enforces type safety without owning your enum.
  • Structured logging — accepts any ILogger<T> compatible with Serilog, NLog, Microsoft Console, or any MEL provider.
  • Low-allocation receive path — uses System.IO.Pipelines for TCP framing and reuses buffers across reads.
  • Zero serialization opinion — payloads are ReadOnlyMemory<byte>; use MessagePack, Protobuf, System.Text.Json, or raw structs.

Installation

dotnet add package Giraffe.Net

Quick Start

1. Define your message types

// Must use ushort as the underlying type — the wire header is 16 bits.
public enum AppMessage : ushort
{
    Login    = 0,
    Chat     = 1,
    Position = 2,
    Ping     = 3,
}

2. Start a server

using Giraffe;
using Giraffe.Messaging;
using Microsoft.Extensions.Logging;

var loggerFactory = LoggerFactory.Create(b => b.AddConsole());

var server = new GiraffeServer<AppMessage>(
    new GiraffeOptions { TcpPort = 7777, UdpPort = 7778 },
    loggerFactory.CreateLogger<GiraffeServer<AppMessage>>());

server.ClientConnected    += id => Console.WriteLine($"Client connected:    {id}");
server.ClientDisconnected += id => Console.WriteLine($"Client disconnected: {id}");

server.MessageReceived += async (connectionId, message, ct) =>
{
    Console.WriteLine($"[{message.MessageType}] from {connectionId}: {message.Payload.Length} bytes");

    // Echo back over TCP
    await server.SendToAsync(connectionId, new GiraffeMessage<AppMessage>
    {
        MessageType = AppMessage.Chat,
        Payload     = message.Payload,
    }, TransportMode.Tcp, ct);
};

await server.StartAsync();
Console.WriteLine("Server running. Press Enter to stop.");
Console.ReadLine();
await server.StopAsync();

3. Connect a client

var client = new GiraffeClient<AppMessage>(
    new GiraffeOptions(),
    loggerFactory.CreateLogger<GiraffeClient<AppMessage>>());

client.MessageReceived += async (message, ct) =>
{
    Console.WriteLine($"Received [{message.MessageType}]: {message.Payload.Length} bytes");
    return; // suppress CS1998
};

await client.ConnectAsync("localhost", tcpPort: 7777, udpPort: 7778);

// Send a reliable message over TCP
await client.SendAsync(new GiraffeMessage<AppMessage>
{
    MessageType = AppMessage.Chat,
    Payload     = System.Text.Encoding.UTF8.GetBytes("Hello, Giraffe!"),
}, TransportMode.Tcp);

// Send a low-overhead position update over UDP
await client.SendAsync(new GiraffeMessage<AppMessage>
{
    MessageType = AppMessage.Position,
    Payload     = new byte[] { 0x01, 0x02, 0x03, 0x04 }, // your encoded position
}, TransportMode.Udp);

await client.DisconnectAsync();

Configuration

All options are set through GiraffeOptions at construction time.

Property Default Description
TcpPort 9000 Port the server listens on for TCP connections
UdpPort 9001 Port the server listens on for UDP datagrams
MaxUdpPayloadBytes 508 Maximum UDP payload in bytes. 508 avoids IP fragmentation over most networks. Raise to 1472 for controlled LAN environments.
MaxTcpPayloadBytes 10485760 (10 MB) Maximum TCP payload the server will accept from a single frame. Protects against malicious peers claiming huge allocations.
TcpBacklog 100 TCP listener backlog (pending connection queue depth)
ConnectTimeout 10s How long ConnectAsync waits before timing out
ReuseAddress true Sets SO_REUSEADDR on both sockets

TCP vs UDP — Choosing the Right Transport

TCP UDP
Delivery guarantee Yes — retransmits lost packets No — packets may be silently dropped
Ordering guarantee Yes — arrives in send order No — packets may arrive out of order
Overhead ~20 bytes IP + ~20 bytes TCP header ~20 bytes IP + ~8 bytes UDP header
Use for Login, chat, game state, commands Position updates, sensor readings, real-time telemetry

Rule of thumb: use TCP for anything where missing a message would corrupt application state. Use UDP for high-frequency data where a dropped update is acceptable because a newer one is coming.


Wire Protocol

Every message — TCP or UDP — is prefixed with an 8-byte header:

Offset  Size  Field          Description
------  ----  -------------  -----------------------------------------
0       1     Magic          0x47 ('G') — identifies a Giraffe frame
1       1     Version        0x01 — protocol version
2       2     MessageType    ushort, big-endian — your enum value
4       4     PayloadLength  uint, big-endian — payload byte count
--- payload follows ---

TCP frames are length-prefixed streams. UDP frames are one datagram per message.


Logging

Giraffe uses Microsoft.Extensions.Logging abstractions. Pass any compatible ILogger<T> at construction:

// Serilog
Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
var loggerFactory = new SerilogLoggerFactory();

// NLog, Microsoft Console, etc. — same pattern

Known Limitations (v1)

  • Server cannot send UDP to a specific client. UDP is connectionless; the server has no reliable way to map a connection ID to a client UDP endpoint without a handshake (planned for v2). Calling server.SendToAsync(..., TransportMode.Udp) throws NotSupportedException.
  • No TLS/encryption. All traffic is plaintext. For production use over the public internet, run Giraffe inside a VPN or WireGuard tunnel. TLS support is planned for v2.
  • No UDP retry or sequencing. The library does not add acknowledgement or ordering on top of UDP. Implement these at the application layer if needed.
  • UDP behind NAT. Packets from two clients behind the same NAT may appear to come from the same endpoint. This affects server-side UDP source identification.

Requirements

  • .NET 10.0 or later
  • The TMessageType enum must use ushort as its underlying type: enum MyMessages : ushort { ... }

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 40 6/3/2026