1 use test_programs::sockets::supports_ipv6;
2 use test_programs::wasi::sockets::network::{
3     IpAddressFamily, IpSocketAddress, Ipv4SocketAddress, Ipv6SocketAddress, Network,
4 };
5 use test_programs::wasi::sockets::tcp::TcpSocket;
6 
7 fn test_tcp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress) {
8     let first_message = b"Hello, world!";
9     let second_message = b"Greetings, planet!";
10 
11     let net = Network::default();
12     let listener = TcpSocket::new(family).unwrap();
13 
14     listener.blocking_bind(&net, bind_address).unwrap();
15     listener.set_listen_backlog_size(32).unwrap();
16     listener.blocking_listen().unwrap();
17 
18     let addr = listener.local_address().unwrap();
19 
20     {
21         let client = TcpSocket::new(family).unwrap();
22         let (_client_input, client_output) = client.blocking_connect(&net, addr).unwrap();
23 
24         client_output.blocking_write_util(&[]).unwrap();
25         client_output.blocking_write_util(first_message).unwrap();
26     }
27 
28     {
29         let (_accepted, input, _output) = listener.blocking_accept().unwrap();
30 
31         let empty_data = input.read(0).unwrap();
32         assert!(empty_data.is_empty());
33 
34         let data = input.blocking_read(first_message.len() as u64).unwrap();
35 
36         // Check that we sent and received our message!
37         assert_eq!(data, first_message); // Not guaranteed to work but should work in practice.
38     }
39 
40     // Another client
41     {
42         let client = TcpSocket::new(family).unwrap();
43         let (_client_input, client_output) = client.blocking_connect(&net, addr).unwrap();
44 
45         client_output.blocking_write_util(second_message).unwrap();
46     }
47 
48     {
49         let (_accepted, input, _output) = listener.blocking_accept().unwrap();
50         let data = input.blocking_read(second_message.len() as u64).unwrap();
51 
52         // Check that we sent and received our message!
53         assert_eq!(data, second_message); // Not guaranteed to work but should work in practice.
54     }
55 }
56 
57 fn main() {
58     test_tcp_sample_application(
59         IpAddressFamily::Ipv4,
60         IpSocketAddress::Ipv4(Ipv4SocketAddress {
61             port: 0,                 // use any free port
62             address: (127, 0, 0, 1), // localhost
63         }),
64     );
65     if supports_ipv6() {
66         test_tcp_sample_application(
67             IpAddressFamily::Ipv6,
68             IpSocketAddress::Ipv6(Ipv6SocketAddress {
69                 port: 0,                           // use any free port
70                 address: (0, 0, 0, 0, 0, 0, 0, 1), // localhost
71                 flow_info: 0,
72                 scope_id: 0,
73             }),
74         );
75     }
76 }
77