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