Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
Nov 30, 2023

How to Use QUIC (Quick UDP Internet Connections) in .NET 7

Автор:
Источник:
Просмотров:
3691

QUIC (Quick UDP Internet Connections) is a new transport protocol for the Internet that runs on top of User Datagram Protocol (UDP)

Night city

QUIC (Quick UDP Internet Connections) is a new transport protocol for the Internet that runs on top of User Datagram Protocol (UDP). It is designed to provide a secure, low-latency, and multiplexed connection between client and server. QUIC aims to improve upon the traditional Transmission Control Protocol (TCP) by reducing the number of round trips required for connection establishment and data transfer, which results in faster page load times and improved user experience.

Why QUIC

QUIC was invented to address the limitations and inefficiencies of the traditional Transmission Control Protocol (TCP) in today’s fast-paced Internet environment. With the increasing use of mobile devices and the need for instant gratification, the traditional TCP has become a bottleneck for delivering fast, reliable and secure online experiences.

QUIC was designed to address these issues by providing a low-latency, multiplexed, and secure transport protocol that can improve the performance and reliability of the Internet. It combines the features of TCP and User Datagram Protocol (UDP) to reduce latency and improve reliability, while adding encryption and multiplexing capabilities. The result is a transport protocol that provides faster and more secure connections compared to traditional TCP.

How it works

QUIC (Quick UDP Internet Connections)

QUIC (Quick UDP Internet Connections) works by creating a secure and reliable connection between a client and a server using User Datagram Protocol (UDP). It uses encryption to protect the data being transmitted, which eliminates the need for a separate security layer like SSL/TLS.

QUIC also uses multiplexing to allow multiple streams of data to be sent over the same connection concurrently, reducing the overhead associated with multiple connections. This eliminates the need for the client to wait for a response from the server before sending additional requests, which improves the overall efficiency of the connection.

QUIC also implements congestion control, which adjusts the flow of data based on network conditions to prevent overloading the network. This results in a faster and more stable connection compared to traditional TCP.

Overall, QUIC provides a fast, secure, and reliable transport protocol for the Internet by combining the best features of TCP and UDP and adding new features to improve the performance and reliability of the connection.

QUIC handshake

QUIC in .Net 7

QUIC (Quick UDP Internet Connections) is supported in .NET 7, which is the latest version of the .NET platform developed by Microsoft. .NET 7 provides support for QUIC in the System.Net.Quic namespace, which provides a set of APIs for creating and managing QUIC connections.

With .NET 7, developers can easily create client and server applications that use QUIC as the transport protocol. They can also take advantage of the benefits provided by QUIC, such as low latency, high performance, and improved security, to build high-quality, fast, and reliable applications.

To use QUIC in .NET 7, developers can start by creating a client or server application and using the System.Net.Quic namespace to create and manage QUIC connections. They can also configure the QUIC connection to match their specific requirements, such as encryption and congestion control.

The support for QUIC in .NET 7 provides developers with a powerful and flexible platform for building fast, reliable, and secure applications that take advantage of the benefits of QUIC as a transport protocol.

An Example

Here’s a simple example to demonstrate how to use QUIC in .NET 7:

Server side:

using System;
using System.Net;
using System.Net.Quic;
using System.Net.Security;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
#pragma warning disable CA1416

namespace QuicExample
{
    [RequiresPreviewFeatures]
    class Program
    {
        static async Task Main(string[] args)
        {
            var isRunning = true;

            if (!QuicListener.IsSupported)
            {
                Console.WriteLine("QUIC is not supported.");
                return;
            }
            var protocol = "quic-test";
            //change to your pfx file path
            var pfxFilePath = "D:\\Medium\\QuicExample\\contoso.com.pfx";
            //change to your pfx file password
            var pfxPassword = "password";
            var port = 8000;

            var serverConnectionOptions = new QuicServerConnectionOptions()
            {
                DefaultStreamErrorCode = 0x0A,
                DefaultCloseErrorCode = 0x0B,                         
                ServerAuthenticationOptions = new SslServerAuthenticationOptions
                {
                    ApplicationProtocols = new List<SslApplicationProtocol>() { new SslApplicationProtocol(protocol) },                    
                    ServerCertificate = new X509Certificate2(pfxFilePath, pfxPassword)
                }
            };            

            var listener = await QuicListener.ListenAsync(new QuicListenerOptions()
            {
                ListenEndPoint = new IPEndPoint(IPAddress.Loopback, port),
                ApplicationProtocols = new List<SslApplicationProtocol>() { new SslApplicationProtocol(protocol) },
                ConnectionOptionsCallback = (_, _, _) => ValueTask.FromResult(serverConnectionOptions)
            });           


            while (isRunning)
            {
                var connection = await listener.AcceptConnectionAsync();
                var stream = await connection.AcceptInboundStreamAsync();
                
                // Work with the incoming stream ...
                var buf = new byte[128];
                var len = await stream.ReadAsync(buf, 0, buf.Length);
                Console.WriteLine(Encoding.UTF8.GetString(buf, 0, len));                
            }

            await listener.DisposeAsync();
        }
    }
}

Server side requires a certificate. You can create a self-signed certificate using PowerShell:

First create the certificate:

New-SelfSignedCertificate -DnsName @("contoso.com", "www.contoso.com") -CertStoreLocation "cert:\LocalMachine\My"

Then export the certificate:

$certKeyPath = "D:\Medium\QuicExample\contoso.com.pfx"
$password = ConvertTo-SecureString 'password' -AsPlainText -Force
$cert | Export-PfxCertificate -FilePath $certKeyPath -Password $password
$rootCert = $(Import-PfxCertificate -FilePath $certKeyPath -CertStoreLocation 'Cert:\LocalMachine\Root' -Password $password)

Client side:

using System;
using System.Net;
using System.Net.Quic;
using System.Net.Security;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
#pragma warning disable CA1416

namespace QuickClientExample
{
    [RequiresPreviewFeatures]
    class Program
    {
        static async Task Main(string[] args)
        {            

            if (!QuicConnection.IsSupported)
            {
                Console.WriteLine("QUIC is not supported.");
                return;
            }

            var protocol = "quic-test";
            var port = 8000;

            var clientConnectionOptions = new QuicClientConnectionOptions()
            {
                RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port),
                DefaultStreamErrorCode = 0x0A,
                DefaultCloseErrorCode = 0x0B,
                MaxInboundUnidirectionalStreams = 10,
                MaxInboundBidirectionalStreams = 100,
                ClientAuthenticationOptions = new SslClientAuthenticationOptions()
                {
                    ApplicationProtocols = new List<SslApplicationProtocol>() { new SslApplicationProtocol(protocol) }
                }
            };
            var connection = await QuicConnection.ConnectAsync(clientConnectionOptions);
            var outgoingStream = await connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);

            var str = "hello world";
            var buf = Encoding.UTF8.GetBytes(str);
            await outgoingStream.WriteAsync(buf, 0, buf.Length);

            Console.ReadKey();

            await connection.CloseAsync(0x0C);
            await connection.DisposeAsync();
        }
    }
}

The example above helps to illustrate some fundamental concepts of the QUIC protocol, such as the use of application protocols, connections, and streams.

You might get a firwall alert when you first time run it.

Windows Security Alert

An application protocol is a set of rules and conventions that govern the exchange of data between a client and a server. Each QUIC connection can support multiple application protocols, each of which is identified by a unique protocol ID. This allows different applications to share the same connection while still maintaining independent streams of data.

A connection in QUIC is a logical connection between a client and a server that provides a reliable and secure transport for exchanging data. Unlike traditional TCP connections, which are based on a single stream of data, QUIC connections can support multiple streams of data in parallel. This allows for more efficient use of network resources and faster data transfer speeds.

A stream in QUIC is a unidirectional or bidirectional flow of data within a connection. Each stream is identified by a unique stream ID, which is used to associate data with a particular stream. Streams can be opened and closed dynamically as needed, allowing applications to send and receive data independently of each other. This provides greater flexibility and control over the data being exchanged, as well as the ability to prioritize different types of data based on their importance.

Together, these concepts provide a powerful and flexible framework for exchanging data over the Internet with the QUIC protocol. By providing a reliable and secure transport, multiple application protocols, and multiple streams of data within a single connection, QUIC allows for more efficient and faster data transfer, improving the overall performance and user experience of Internet applications.

QUIC Protocol
 |
 +-- Protocal 1
 |    |
 |    +-- Connection
 |    |    |
 |    |    +-- Stream
 |    |    |
 |    |    +-- Stream
 |    |    |
 |    |    +-- Stream
 |    |    |
 |    |    ...
 |    |
 |    +-- Connection
 |         |
 |         +-- Stream
 |         |
 |         +-- Stream
 |         |
 |         +-- Stream
 |         |
 |         ...
 |
 +-- Protocol 2
      |
      +-- Connection
           |
           +-- Stream
           |
           +-- Stream
           |
           +-- Stream
           |
           ...

The support for QUIC in .NET 7 is a significant step forward for the .NET ecosystem and the wider internet, as it enables the development of fast and reliable applications. Overall, the addition of QUIC support in .NET 7 is a positive development for both developers and users, as it opens up new possibilities for building fast and efficient applications.

GitHub: https://github.com/devedium/QuicExample

***

References

Похожее
May 29, 2023
Maximizing performance in asynchronous programming Task and Task<TResult> The Task and Task<TResult> types were introduced in .NET 4.0 as part of the Task Parallel Library (TPL) in 2010, which provided a new model for writing multithreaded and asynchronous code. For...
May 12, 2023
Author: Alex Maher
Language Integrated Query (LINQ) is a powerful feature in C# .NET that allows developers to query various data sources using a consistent syntax. In this article, we’ll explore some advanced LINQ techniques to help you level up your skills and...
May 8, 2023
Author: Waqas Ahmed
Dapper is a lightweight ORM (Object-Relational Mapping) framework for .NET Core and is commonly used to query databases in .NET Core applications. Here are some of the advanced features of Dapper in .NET Core: Multi-Mapping: Dapper allows you to map...
Jul 11, 2021
Author: Sasha Mathews
In C#, reference types can be assigned null values. This is something that developers will have to live with until they use classes to create software. Unfortunately, the folks at Microsoft cannot simply disallow null assignment to reference variables at...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Стили именования переменных и функций. Используйте их все
10 историй, как «валят» айтишников на технических интервью
Функции и хранимые процедуры в PostgreSQL: зачем нужны и как применять в реальных примерах
Семь итераций наивности или как я полтора года свою дебютную игру писал
Вопросы с собеседований, которые означают не то, что вы думаете
Путеводитель по репликации баз данных
5 приемов увеличения продуктивности разработчика
Топ 8 лучших ресурсов для практики программирования в 2018
Использование SQLite в .NET приложениях
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile