1 | use std::io; |
2 | |
3 | #[cfg (windows)] |
4 | async fn windows_main() -> io::Result<()> { |
5 | use tokio::io::AsyncWriteExt; |
6 | use tokio::io::{AsyncBufReadExt, BufReader}; |
7 | use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions}; |
8 | |
9 | const PIPE_NAME: &str = r"\\.\pipe\named-pipe-single-client" ; |
10 | |
11 | let server = ServerOptions::new().create(PIPE_NAME)?; |
12 | |
13 | let server = tokio::spawn(async move { |
14 | // Note: we wait for a client to connect. |
15 | server.connect().await?; |
16 | |
17 | let mut server = BufReader::new(server); |
18 | |
19 | let mut buf = String::new(); |
20 | server.read_line(&mut buf).await?; |
21 | server.write_all(b"pong \n" ).await?; |
22 | Ok::<_, io::Error>(buf) |
23 | }); |
24 | |
25 | let client = tokio::spawn(async move { |
26 | // There's no need to use a connect loop here, since we know that the |
27 | // server is already up - `open` was called before spawning any of the |
28 | // tasks. |
29 | let client = ClientOptions::new().open(PIPE_NAME)?; |
30 | |
31 | let mut client = BufReader::new(client); |
32 | |
33 | let mut buf = String::new(); |
34 | client.write_all(b"ping \n" ).await?; |
35 | client.read_line(&mut buf).await?; |
36 | Ok::<_, io::Error>(buf) |
37 | }); |
38 | |
39 | let (server, client) = tokio::try_join!(server, client)?; |
40 | |
41 | assert_eq!(server?, "ping \n" ); |
42 | assert_eq!(client?, "pong \n" ); |
43 | |
44 | Ok(()) |
45 | } |
46 | |
47 | #[tokio::main] |
48 | async fn main() -> io::Result<()> { |
49 | #[cfg (windows)] |
50 | { |
51 | windows_main().await?; |
52 | } |
53 | |
54 | #[cfg (not(windows))] |
55 | { |
56 | println!("Named pipes are only supported on Windows!" ); |
57 | } |
58 | |
59 | Ok(()) |
60 | } |
61 | |