1
1
use bastion:: prelude:: * ;
2
+ #[ cfg( not( target_os = "windows" ) ) ]
2
3
use futures:: io;
3
- use std:: net:: { TcpListener , TcpStream } ;
4
+ #[ cfg( target_os = "windows" ) ]
5
+ use std:: io:: { self , Read , Write } ;
6
+ use std:: net:: { TcpListener , TcpStream , ToSocketAddrs } ;
4
7
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
5
8
9
+ #[ cfg( not( target_os = "windows" ) ) ]
10
+ async fn run ( addr : impl ToSocketAddrs ) -> io:: Result < ( ) > {
11
+ let listener = Handle :: < TcpListener > :: bind ( addr) . unwrap ( ) ;
12
+ println ! ( "Listening on {}" , listener. get_ref( ) . local_addr( ) . unwrap( ) ) ;
13
+
14
+ // Accept clients in a loop.
15
+ loop {
16
+ let ( stream, peer_addr) = listener. accept ( ) . await . unwrap ( ) ;
17
+ println ! ( "Accepted client: {}" , peer_addr) ;
18
+
19
+ // Spawn a task that echoes messages from the client back to it.
20
+ spawn ( echo ( stream) ) ;
21
+ }
22
+ Ok ( ( ) )
23
+ }
24
+
25
+ #[ cfg( target_os = "windows" ) ]
26
+ async fn run ( addr : impl ToSocketAddrs ) -> io:: Result < ( ) > {
27
+ let listener = std:: net:: TcpListener :: bind ( addr) . unwrap ( ) ;
28
+ println ! ( "Listening on {}" , listener. local_addr( ) . unwrap( ) ) ;
29
+
30
+ // Accept clients in a loop.
31
+ for stream in listener. incoming ( ) {
32
+ match stream {
33
+ Ok ( stream) => {
34
+ println ! ( "Accepted client" ) ;
35
+ spawn ! ( echo( stream) ) ;
36
+ }
37
+ _ => {
38
+ break ;
39
+ }
40
+ }
41
+ }
42
+ Ok ( ( ) )
43
+ }
44
+
45
+ #[ cfg( not( target_os = "windows" ) ) ]
6
46
async fn echo ( stream : Handle < TcpStream > ) -> io:: Result < ( ) > {
7
47
io:: copy ( & stream, & mut & stream) . await ?;
8
48
Ok ( ( ) )
9
49
}
10
50
51
+ #[ cfg( target_os = "windows" ) ]
52
+ async fn echo ( mut stream : TcpStream ) -> io:: Result < ( ) > {
53
+ let mut buf = [ 0 as u8 ; 256 ] ;
54
+ while let Ok ( size) = stream. read ( & mut buf) {
55
+ stream. write ( & buf[ 0 ..size] ) . unwrap ( ) ;
56
+ }
57
+ Ok ( ( ) )
58
+ }
59
+
11
60
const TCP_SERVER_COUNT : usize = 10 ;
12
61
static TCP_SERVERS : AtomicUsize = AtomicUsize :: new ( TCP_SERVER_COUNT ) ;
13
62
@@ -17,7 +66,8 @@ static TCP_SERVERS: AtomicUsize = AtomicUsize::new(TCP_SERVER_COUNT);
17
66
/// Prologue:
18
67
///
19
68
/// This example demonstrates using 10 parallel tcp servers
20
-
69
+ /// non windows versions use io::copy from nuclei
70
+ /// windows versions use a regular stream copy
21
71
fn main ( ) {
22
72
env_logger:: init ( ) ;
23
73
@@ -26,26 +76,14 @@ fn main() {
26
76
let _tcp_servers = Bastion :: children ( |children : Children | {
27
77
children
28
78
. with_redundancy ( TCP_SERVER_COUNT ) // Let's have 10 tcp echo servers :)
29
- . with_exec ( move |_ctx : BastionContext | {
30
- async move {
31
- println ! ( "Server is starting!" ) ;
32
- let port = TCP_SERVERS . fetch_sub ( 1 , Ordering :: SeqCst ) + 2000 ;
33
- let addr = format ! ( "127.0.0.1:{}" , port) ;
34
-
35
- let listener = Handle :: < TcpListener > :: bind ( addr) . unwrap ( ) ;
36
- println ! ( "Listening on {}" , listener. get_ref( ) . local_addr( ) . unwrap( ) ) ;
37
-
38
- // Accept clients in a loop.
39
- loop {
40
- let ( stream, peer_addr) = listener. accept ( ) . await . unwrap ( ) ;
41
- println ! ( "Accepted client: {}" , peer_addr) ;
42
-
43
- // Spawn a task that echoes messages from the client back to it.
44
- spawn ( echo ( stream) ) ;
45
- }
46
-
47
- Ok ( ( ) )
48
- }
79
+ . with_exec ( move |_ctx : BastionContext | async move {
80
+ println ! ( "Server is starting!" ) ;
81
+ let port = TCP_SERVERS . fetch_sub ( 1 , Ordering :: SeqCst ) + 2000 ;
82
+ let addr = format ! ( "127.0.0.1:{}" , port) ;
83
+
84
+ run ( addr) ;
85
+
86
+ Ok ( ( ) )
49
87
} )
50
88
} )
51
89
. expect ( "Couldn't start a new children group." ) ;
0 commit comments