From f43d427709941dc76a9f9ed9986bedfb46d9c756 Mon Sep 17 00:00:00 2001 From: djc Date: Tue, 23 Feb 2021 08:51:41 +0000 Subject: [PATCH] deploy: 1a62da82a0bcd38db72211130dc7ea66f054f5d7 --- 404.html | 2 +- index.html | 2 +- print.html | 122 +++++++++++- quic.html | 6 +- quinn.html | 2 +- quinn/certificate.html | 2 +- quinn/data-transfer.html | 354 +++++++++++++++++++++++++++++++++++ quinn/set-up-connection.html | 6 +- searchindex.js | 2 +- searchindex.json | 2 +- 10 files changed, 487 insertions(+), 13 deletions(-) create mode 100644 quinn/data-transfer.html diff --git a/404.html b/404.html index a4b2a1137..3822d08ed 100644 --- a/404.html +++ b/404.html @@ -97,7 +97,7 @@ diff --git a/index.html b/index.html index e435df1a4..7243e6cee 100644 --- a/index.html +++ b/index.html @@ -95,7 +95,7 @@ diff --git a/print.html b/print.html index b2d339906..2dfff0fe3 100644 --- a/print.html +++ b/print.html @@ -97,7 +97,7 @@ @@ -461,6 +461,126 @@ The SERVER_NAME argument is the DNS name, matching the certificate



Next up, let's have a look at sending data over this connection.

+

Data Transfer

+

The previous chapter explained how to set up an Endpoint +and then get access to a NewConnection instance. +This chapter continues with the subject of sending data over this connection.

+

Multiplexing

+

Multiplexing is the act of combining data from multiple streams into a single stream. +This can have a significant positive effect on the performance of the application. +With QUIC, the programmer is in full control over the stream allocation.

+

Stream Types

+

QUIC provides support for both stream and message-based communication. +Streams and messages can be initiated both on the client and server.

+ + + + +
TypeDescriptionReference
Bidirectional Streamtwo way stream communication.see open_bi
Unidirectional Streamone way stream communication.see open_uni
Unreliable Messaging (extension)message based unreliable communication.see send_datagram
+

How to Use

+

New streams can be created with open_bi(), open_uni() from type Connection. +An instance of this type, together with existing streams, can be found in the connection field of NewConnection.

+

Bidirectional Streams

+

With bidirectional streams, data can be sent in both directions. +For example, from the connection initiator to the peer and the other way around.

+

open bidirectional stream

+

+#![allow(unused)]
+fn main() {
+async fn open_bidirectional_stream(connection: Connection) -> anyhow::Result<()> {
+    let (mut send, recv) = connection.
+        open_bi()
+        .await?;
+
+    send.write_all(b"test").await?;
+    send.finish().await?;
+    
+    let received = recv.read_to_end(10).await?;
+
+    Ok(())
+}
+}
+
+

iterate incoming bidirectional stream(s)

+

+#![allow(unused)]
+fn main() {
+async fn receive_bidirectional_stream(mut connection: NewConnection) -> anyhow::Result<()> {
+    while let Some(Ok((send, recv))) = connection.bi_streams.next().await {
+        // Because it is a bidirectional stream, we can both send and recieve.
+        println!("request: {:?}", recv.read_to_end(50).await?);
+
+        send.write_all(b"response").await?;
+        send.finish().await?;
+    }
+
+    Ok(())
+}
+}
+
+

Unidirectional Streams

+

With unidirectional streams, you can carry data only in one direction: from the initiator of the stream to its peer. +It is possible to get reliability without ordering (so no head-of-line blocking) by opening a new stream for each packet.

+

open unidirectional stream

+

+#![allow(unused)]
+fn main() {
+async fn open_unidirectional_stream(connection: Connection)-> anyhow::Result<()> {
+    let mut send = connection.
+        open_uni()
+        .await?;
+
+    send.write_all(b"test").await.unwrap();
+    send.finish().await?;
+
+    Ok(())
+}
+}
+
+

iterating incoming unidirectional stream(s)

+

+#![allow(unused)]
+fn main() {
+async fn receive_unidirectional_stream(mut connection: NewConnection) -> anyhow::Result<()> {
+    while let Some(Ok(recv)) = connection.uni_streams.next().await {
+        // Because it is a unidirectional stream, we can only receive not send back.
+        println!("{:?}", recv.read_to_end(50).await?);
+    }
+
+    Ok(())
+}
+}
+
+

Unreliable Messaging

+

With unreliable messaging, you can transfer data without reliability. +This could be useful if data arrival isn't essential or when high throughput is important.

+

send datagram

+

+#![allow(unused)]
+fn main() {
+async fn send_unreliable(connection: Connection)-> anyhow::Result<()> {
+    connection
+        .send_datagram(b"test".into())
+        .await?;
+
+    Ok(())
+}
+}
+
+

iterating datagram stream(s)

+

+#![allow(unused)]
+fn main() {
+async fn receive_datagram(mut connection: NewConnection) -> anyhow::Result<()> {
+    while let Some(Ok(received_bytes)) = connection.datagrams.next().await {
+        // Because it is a unidirectional stream, we can only receive not send back.
+        println!("request: {:?}", received);
+    }
+
+    Ok(())
+}
+}
+

The QUIC protocol

QUIC is a general-purpose network protocol built on top of UDP. The protocol is still under development and standardized by the IETF. diff --git a/quic.html b/quic.html index 274df1245..5a9813da7 100644 --- a/quic.html +++ b/quic.html @@ -95,7 +95,7 @@

@@ -189,7 +189,7 @@ One thing is for sure, QUIC has many great potentials and will serve us in the f