All Projects → scalablecory → Networktoolkit

scalablecory / Networktoolkit

Licence: mit
This project contains networking primitives for use with .NET.

Projects that are alternatives of or similar to Networktoolkit

Bedrockframework
High performance, low level networking APIs for building custom servers and clients.
Stars: ✭ 697 (+881.69%)
Mutual labels:  networking, sockets
Libzt
ZeroTier Sockets - Put a network stack in your app
Stars: ✭ 486 (+584.51%)
Mutual labels:  networking, sockets
Python Zeroless
ZeroMQ for Pythonistas™
Stars: ✭ 140 (+97.18%)
Mutual labels:  networking, sockets
Python Voice Chat
Instant multi-person voice chat over the internet in Python 3
Stars: ✭ 51 (-28.17%)
Mutual labels:  networking, sockets
Netmap Tutorial
Netmap tutorial at SIGCOMM 2017 and AsiaBSDCon 2018
Stars: ✭ 60 (-15.49%)
Mutual labels:  networking
Ipfsfb
InterPlanetary File System for Business (IPFSfB) is an enterprise blockchain storage network based on InterPlanetary File System.
Stars: ✭ 57 (-19.72%)
Mutual labels:  networking
Unifi exporter
Multiarch images for scraping Prometheus metrics from a Unifi Controller. Kubernetes / prometheus-operator compatible.
Stars: ✭ 54 (-23.94%)
Mutual labels:  networking
Odp Dpdk
OpenDataPlane DPDK platform implementation
Stars: ✭ 52 (-26.76%)
Mutual labels:  networking
Lance
Multiplayer game server based on Node.JS
Stars: ✭ 1,161 (+1535.21%)
Mutual labels:  networking
Fetch
The best file downloader library for Android
Stars: ✭ 1,124 (+1483.1%)
Mutual labels:  networking
Mqtt
MQTT broker written in D, using vibe.d
Stars: ✭ 59 (-16.9%)
Mutual labels:  networking
Notifier
NO LIBRARIES socket per page bridge for your Laravel application. (CLIENT PART INCLUDED)
Stars: ✭ 57 (-19.72%)
Mutual labels:  sockets
Squid
Declarative and Reactive Networking for Swift.
Stars: ✭ 61 (-14.08%)
Mutual labels:  networking
Jus
Flexible and Easy HTTP/REST Communication library for Java and Android
Stars: ✭ 55 (-22.54%)
Mutual labels:  networking
Netdynamics
Data-oriented networking playground for the reliable UDP transports
Stars: ✭ 65 (-8.45%)
Mutual labels:  networking
Ipconnect
P2P Chat and File Transfer Desktop Application
Stars: ✭ 53 (-25.35%)
Mutual labels:  sockets
Udt C
A basic implementation of UDP-based Data Transfer protocol (UDT) in C
Stars: ✭ 59 (-16.9%)
Mutual labels:  sockets
Nmstate
Nmstate is a library with an accompanying command line tool that manages host networking settings in a declarative manner.
Stars: ✭ 63 (-11.27%)
Mutual labels:  networking
Avenue
Wrapper around URLSession and URLSessionTask to enable seamless integration with Operation / OperationQueue.
Stars: ✭ 58 (-18.31%)
Mutual labels:  networking
Icmplib
Easily forge ICMP packets and make your own ping and traceroute.
Stars: ✭ 58 (-18.31%)
Mutual labels:  sockets

NetworkToolkit

This project contains networking primitives for use with .NET. It can be obtained from NuGet. Nuget

This is a bit of a prototyping playground right now and APIs will not be perfectly stable.

HTTP Primitives

NetworkToolkit provides a lower-level HTTP client that prioritizes performance and flexibility. Once warmed up, it processes requests using zero allocations.

Performance

In the great majority of cases, HttpClient will be fast enough. Generally I/O will dominate a request's total time. However, if peak perf is needed, this library will be faster, especially as the number of headers in the request/response increase.

Benchmarks are incomplete, so this should not be viewed as an exhaustive comparison:

Method RequestHeaders ResponseBytes Mean Error StdDev Median Ratio RatioSD
Primitive Minimal Minimal 10.806 us 0.3304 us 0.9741 us 10.985 us 0.51 0.05
PrimitivePrepared Minimal Minimal 9.278 us 0.2091 us 0.6066 us 9.298 us 0.44 0.04
SocketsHandler Minimal Minimal 21.323 us 0.4380 us 1.2136 us 21.442 us 1.00 0.00
Primitive Minimal StackOverflow 13.665 us 0.6509 us 1.9089 us 13.187 us 0.16 0.02
PrimitivePrepared Minimal StackOverflow 14.108 us 0.6328 us 1.8559 us 13.432 us 0.17 0.03
SocketsHandler Minimal StackOverflow 86.356 us 1.7149 us 4.2707 us 87.476 us 1.00 0.00
Primitive Normal Minimal 11.053 us 0.2498 us 0.7366 us 11.149 us 0.32 0.03
PrimitivePrepared Normal Minimal 10.636 us 0.2867 us 0.8455 us 10.701 us 0.31 0.03
SocketsHandler Normal Minimal 34.775 us 0.6940 us 1.9231 us 35.172 us 1.00 0.00
Primitive Normal StackOverflow 15.080 us 0.6158 us 1.7866 us 14.874 us 0.16 0.03
PrimitivePrepared Normal StackOverflow 13.964 us 0.5963 us 1.7490 us 13.257 us 0.15 0.02
SocketsHandler Normal StackOverflow 94.221 us 2.4801 us 7.3127 us 96.337 us 1.00 0.00

A simple GET request using exactly one HTTP/1 connection, no pooling

Avoid a connection pool to have exact control over connections.

await using ConnectionFactory connectionFactory = new SocketConnectionFactory();
await using Connection connection = await connectionFactory.ConnectAsync(new DnsEndPoint("microsoft.com", 80));
await using HttpConnection httpConnection = new Http1Connection(connection);
await using ValueHttpRequest request = (await httpConnection.CreateNewRequestAsync(HttpPrimitiveVersion.Version11, HttpVersionPolicy.RequestVersionExact)).Value;

request.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false);
request.WriteRequest(HttpMethod.Get, new Uri("http://microsoft.com"));
request.WriteHeader("Accept", "text/html");
await request.CompleteRequestAsync();

await request.ReadToFinalResponseAsync();
Console.WriteLine($"Got response {request.StatusCode}.");

if(await request.ReadToHeadersAsync())
{
    await request.ReadHeadersAsync(...);
}

if(await request.ReadToContentAsync())
{
    int len;
    byte[] buffer = ArrayPool<byte>.Shared.Rent(4096);

    do
    {
        while((len = await request.ReadContentAsync(buffer)) != 0)
        {
            ForwardData(buffer[..len]);
        }
    }
    while(await request.ReadToNextContentAsync());

    ArrayPool<byte>.Shared.Return(buffer);
}

await request.DrainAsync();

Using the opt-in connection pool

A single-host connection pool handles concurrent HTTP/1 requests, H2C upgrade, ALPN negotiation for HTTP/2, etc.

await using ConnectionFactory connectionFactory = new SocketConnectionFactory();
await using HttpConnection httpConnection = new PooledHttpConnection(connectionFactory, new DnsEndPoint("microsoft.com", 80), sslTargetHost: null);
await using ValueHttpRequest request = (await httpConnection.CreateNewRequestAsync(HttpPrimitiveVersion.Version11, HttpVersionPolicy.RequestVersionExact)).Value;

Optimize frequently-used headers

Prepare frequently-used headers to reduce CPU costs by pre-validating and caching protocol encoding. In the future, this will light up dynamic table compression in HTTP/2 and HTTP/3.

PreparedHeaderSet preparedHeaders = new PreparedHeaderSet()
{
    { "User-Agent", "NetworkToolkit" },
    { "Accept", "text/html" }
};

await using ValueHttpRequest request = ...;

request.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false);
request.WriteRequest(HttpMethod.Get, new Uri("http://microsoft.com"));
request.WriteHeader(preparedHeaders);

Avoiding strings

Avoid string and Uri allocations, optimize away some related processing, and get tight control over encoding by passing in ReadOnlySpan<byte>:

ReadOnlySpan<byte> method = HttpRequest.GetMethod; // "GET"
ReadOnlySpan<byte> authority = ...; // "microsoft.com:80"
ReadOnlySpan<byte> pathAndQuery = ...; // "/"

ReadOnlySpan<byte> headerName = ...; // "Accept"
ReadOnlySpan<byte> headerValue = ...; // "text/html"

await using ValueHttpRequest request = ...;
request.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false);
request.WriteRequest(method, authority, pathAndQuery);
request.WriteHeader(headerName, headerValue);

Advanced processing

Access extensions like HTTP/2 ALT-SVC frames, or efficiently forward requests (reverse proxy) by processing requests as a loosely structured stream:

await using ValueHttpRequest request = ...;
while(await request.ReadAsync() != HttpReadType.EndOfStream)
{
    switch(request.ReadType)
    {
    case HttpReadType.InformationalResponse:
        ProcessInformationalResponse(request.StatusCode, request.Version);
        break;
    case HttpReadType.FinalResponse:
        ProcessResponse(request.StatusCode, request.Version);
        break;
    case HttpReadType.Headers:
        await request.ReadHeadersAsync(...);
        break;
    case HttpReadType.Content:
        int len;
        byte[] buffer = ArrayPool<byte>.Shared.Rent(4096);

        while((len = await request.ReadContentAsync(buffer)) != 0)
        {
            ForwardData(buffer[..len]);
        }

        ArrayPool<byte>.Shared.Return(buffer);
        break;
    case HttpReadType.TrailingHeaders:
        await request.ReadHeadersAsync(...);
        break;
    case HttpReadType.AltSvc:
        ProcessAltSvc(request.AltSvc);
        break;
    }
}

Connection Abstractions

Connection abstractions used to abstract establishment of Stream-based connections.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].