tcp_handler/protocols/
raw.rs

1//! Raw protocol. Without encryption and compression.
2//!
3//! Not recommend. It's unsafe but really fast.
4//!
5//! # Examples
6//! ```rust
7//! use anyhow::Result;
8//! use bytes::{Buf, BufMut, BytesMut};
9//! use tcp_handler::protocols::raw::*;
10//! use tokio::net::{TcpListener, TcpStream};
11//! use variable_len_reader::{VariableReader, VariableWriter};
12//!
13//! #[tokio::main]
14//! async fn main() -> Result<()> {
15//!     let server = TcpListener::bind("localhost:0").await?;
16//!     let mut client = TcpStream::connect(server.local_addr()?).await?;
17//!     let (mut server, _) = server.accept().await?;
18//!
19//!     let c_init = client_init(&mut client, "test", "0").await;
20//!     let s_init = server_init(&mut server, "test", |v| v == "0").await;
21//!     server_start(&mut server, "test", "0", s_init).await?;
22//!     client_start(&mut client, c_init).await?;
23//!
24//!     let mut writer = BytesMut::new().writer();
25//!     writer.write_string("hello server.")?;
26//!     send(&mut client, &mut writer.into_inner()).await?;
27//!
28//!     let mut reader = recv(&mut server).await?.reader();
29//!     let message = reader.read_string()?;
30//!     assert_eq!("hello server.", message);
31//!
32//!     let mut writer = BytesMut::new().writer();
33//!     writer.write_string("hello client.")?;
34//!     send(&mut server, &mut writer.into_inner()).await?;
35//!
36//!     let mut reader = recv(&mut client).await?.reader();
37//!     let message = reader.read_string()?;
38//!     assert_eq!("hello client.", message);
39//!
40//!     Ok(())
41//! }
42//! ```
43//!
44//! The send process:
45//! ```text
46//!         ┌────┬────────┬────────────┐ (It may not be in contiguous memory.)
47//! in  --> │ ** │ ****** │ ********** │
48//!         └────┴────────┴────────────┘
49//!           │
50//!           │─ Directly send packet
51//! out <--  ─┘
52//! ```
53//! The recv process:
54//! ```text
55//!         ┌────────────────────┐ (Packet data.)
56//! in  --> │ ****************** │
57//!         └────────────────────┘
58//!           │
59//!           │─ Directly recv packet
60//! out <--  ─┘
61//! ```
62
63use bytes::{Buf, BytesMut};
64use tokio::io::{AsyncRead, AsyncWrite};
65use crate::protocols::common::*;
66
67/// Init the client side in tcp-handler raw protocol.
68///
69/// Must be used in conjunction with [`client_start`].
70///
71/// # Arguments
72///  * `stream` - The tcp stream or `WriteHalf`.
73///  * `identifier` - The identifier of your application.
74///  * `version` - Current version of your application.
75///
76/// # Example
77/// ```rust,no_run
78/// use anyhow::Result;
79/// use tcp_handler::protocols::raw::{client_init, client_start};
80/// use tokio::net::TcpStream;
81///
82/// #[tokio::main]
83/// async fn main() -> Result<()> {
84///     let mut client = TcpStream::connect("localhost:25564").await?;
85///     let c_init = client_init(&mut client, "test", "0").await;
86///     client_start(&mut client, c_init).await?;
87///     // Now the client is ready to use.
88///     Ok(())
89/// }
90/// ```
91#[inline]
92pub async fn client_init<W: AsyncWrite + Unpin>(stream: &mut W, identifier: &str, version: &str) -> Result<(), StarterError> {
93    write_head(stream, ProtocolVariant::Raw, identifier, version).await?;
94    flush(stream).await?;
95    Ok(())
96}
97
98/// Init the server side in tcp-handler raw protocol.
99///
100/// Must be used in conjunction with [`server_start`].
101///
102/// # Arguments
103///  * `stream` - The tcp stream or `ReadHalf`.
104///  * `identifier` - The identifier of your application.
105///  * `version` - A prediction to determine whether the client version is allowed.
106///
107/// # Example
108/// ```rust,no_run
109/// use anyhow::Result;
110/// use tcp_handler::protocols::raw::{server_init, server_start};
111/// use tokio::net::TcpListener;
112///
113/// #[tokio::main]
114/// async fn main() -> Result<()> {
115///     let server = TcpListener::bind("localhost:25564").await?;
116///     let (mut server, _) = server.accept().await?;
117///     let s_init = server_init(&mut server, "test", |v| v == "0").await;
118///     server_start(&mut server, "test", "0", s_init).await?;
119///     // Now the server is ready to use.
120///     Ok(())
121/// }
122/// ```
123#[inline]
124pub async fn server_init<R: AsyncRead + Unpin, P: FnOnce(&str) -> bool>(stream: &mut R, identifier: &str, version: P) -> Result<(u16, String), StarterError> {
125    read_head(stream, ProtocolVariant::Raw, identifier, version).await
126}
127
128/// Make sure the client side is ready to use in tcp-handler raw protocol.
129///
130/// Must be used in conjunction with [`client_init`].
131///
132/// # Arguments
133///  * `stream` - The tcp stream or `ReadHalf`.
134///  * `last` - The return value of [`client_init`].
135///
136/// # Example
137/// ```rust,no_run
138/// use anyhow::Result;
139/// use tcp_handler::protocols::raw::{client_init, client_start};
140/// use tokio::net::TcpStream;
141///
142/// #[tokio::main]
143/// async fn main() -> Result<()> {
144///     let mut client = TcpStream::connect("localhost:25564").await?;
145///     let c_init = client_init(&mut client, "test", "0").await;
146///     client_start(&mut client, c_init).await?;
147///     // Now the client is ready to use.
148///     Ok(())
149/// }
150/// ```
151#[inline]
152pub async fn client_start<R: AsyncRead + Unpin>(stream: &mut R, last: Result<(), StarterError>) -> Result<(), StarterError> {
153    read_last(stream, last).await
154}
155
156/// Make sure the server side is ready to use in tcp-handler raw protocol.
157///
158/// Must be used in conjunction with [`server_init`].
159///
160/// # Arguments
161///  * `stream` - The tcp stream or `WriteHalf`.
162///  * `identifier` - The returned application identifier.
163/// (Should be same with the para in [`server_init`].)
164///  * `version` - The returned recommended application version.
165/// (Should be passed the prediction in [`server_init`].)
166///  * `last` - The return value of [`server_init`].
167///
168/// # Example
169/// ```rust,no_run
170/// use anyhow::Result;
171/// use tcp_handler::protocols::raw::{server_init, server_start};
172/// use tokio::net::TcpListener;
173///
174/// #[tokio::main]
175/// async fn main() -> Result<()> {
176///     let server = TcpListener::bind("localhost:25564").await?;
177///     let (mut server, _) = server.accept().await?;
178///     let s_init = server_init(&mut server, "test", |v| v == "0").await;
179///     let (protocol_version, client_version) = server_start(&mut server, "test", "0", s_init).await?;
180///     // Now the server is ready to use.
181///     # let _ = protocol_version;
182///     # let _ = client_version;
183///     Ok(())
184/// }
185/// ```
186#[inline]
187pub async fn server_start<W: AsyncWrite + Unpin>(stream: &mut W, identifier: &str, version: &str, last: Result<(u16, String), StarterError>) -> Result<(u16, String), StarterError> {
188    let res = write_last(stream, ProtocolVariant::Raw, identifier, version, last).await?;
189    flush(stream).await?;
190    Ok(res)
191}
192
193/// Send the message in tcp-handler raw protocol.
194///
195/// # Arguments
196///  * `stream` - The tcp stream or `WriteHalf`.
197///  * `message` - The message to send.
198///
199/// # Example
200/// ```rust,no_run
201/// # use anyhow::Result;
202/// # use bytes::{BufMut, BytesMut};
203/// # use tcp_handler::protocols::raw::{client_init, client_start};
204/// use tcp_handler::protocols::raw::send;
205/// # use tokio::net::TcpStream;
206/// # use variable_len_reader::VariableWriter;
207///
208/// # #[tokio::main]
209/// # async fn main() -> Result<()> {
210/// #     let mut client = TcpStream::connect("localhost:25564").await?;
211/// #     let c_init = client_init(&mut client, "test", "0").await;
212/// #     client_start(&mut client, c_init).await?;
213/// let mut buffer = BytesMut::new().writer();
214/// buffer.write_string("hello server!")?;
215/// send(&mut client, &mut buffer.into_inner()).await?;
216/// #     Ok(())
217/// # }
218/// ```
219#[inline]
220pub async fn send<W: AsyncWrite + Unpin, B: Buf>(stream: &mut W, message: &mut B) -> Result<(), PacketError> {
221    write_packet(stream, message).await?;
222    flush(stream).await?;
223    Ok(())
224}
225
226/// Recv the message in tcp-handler raw protocol.
227///
228/// # Arguments
229///  * `stream` - The tcp stream or `ReadHalf`.
230///
231/// # Example
232/// ```rust,no_run
233/// # use anyhow::Result;
234/// # use bytes::Buf;
235/// # use tcp_handler::protocols::raw::{server_init, server_start};
236/// use tcp_handler::protocols::raw::recv;
237/// # use tokio::net::TcpListener;
238/// # use variable_len_reader::VariableReader;
239///
240/// # #[tokio::main]
241/// # async fn main() -> Result<()> {
242/// #     let server = TcpListener::bind("localhost:25564").await?;
243/// #     let (mut server, _) = server.accept().await?;
244/// #     let s_init = server_init(&mut server, "test", |v| v == "0").await;
245/// #     server_start(&mut server, "test", "0", s_init).await?;
246/// let mut reader = recv(&mut server).await?.reader();
247/// let message = reader.read_string()?;
248/// #     let _ = message;
249/// #     Ok(())
250/// # }
251/// ```
252#[inline]
253pub async fn recv<R: AsyncRead + Unpin>(stream: &mut R) -> Result<BytesMut, PacketError> {
254    read_packet(stream).await
255}
256
257#[cfg(test)]
258mod tests {
259    use anyhow::Result;
260    use bytes::{BufMut, BytesMut};
261    use variable_len_reader::{VariableReader, VariableWriter};
262    use crate::protocols::common::tests::create;
263    use crate::protocols::raw::*;
264
265    #[tokio::test]
266    async fn connect() -> Result<()> {
267        let (mut client, mut server) = create().await?;
268        let c = client_init(&mut client, "a", "1").await;
269        let s = server_init(&mut server, "a", |v| v == "1").await;
270        server_start(&mut server, "a", "1", s).await?;
271        client_start(&mut client, c).await?;
272for _ in 0..10 {
273        let mut writer = BytesMut::new().writer();
274        writer.write_string("hello server in raw.")?;
275        send(&mut client, &mut writer.into_inner()).await?;
276
277        let mut reader = recv(&mut server).await?.reader();
278        let message = reader.read_string()?;
279        assert_eq!("hello server in raw.", message);
280
281        let mut writer = BytesMut::new().writer();
282        writer.write_string("hello client in raw.")?;
283        send(&mut server, &mut writer.into_inner()).await?;
284
285        let mut reader = recv(&mut client).await?.reader();
286        let message = reader.read_string()?;
287        assert_eq!("hello client in raw.", message);
288}
289        Ok(())
290    }
291}