• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Test a simple IPv4 socket server and client.
2 //!
3 //! The client send a message and the server sends one back.
4 
5 #![cfg(not(any(target_os = "redox", target_os = "wasi")))]
6 
7 use rustix::net::{
8     accept, bind_v4, connect_v4, getsockname, listen, recv, send, socket, AddressFamily, Ipv4Addr,
9     Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, SocketType,
10 };
11 use std::sync::{Arc, Condvar, Mutex};
12 use std::thread;
13 
14 const BUFFER_SIZE: usize = 20;
15 
server(ready: Arc<(Mutex<u16>, Condvar)>)16 fn server(ready: Arc<(Mutex<u16>, Condvar)>) {
17     let connection_socket =
18         socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap();
19 
20     let name = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 0);
21     bind_v4(&connection_socket, &name).unwrap();
22 
23     let who = match getsockname(&connection_socket).unwrap() {
24         SocketAddrAny::V4(addr) => addr,
25         _ => panic!(),
26     };
27 
28     listen(&connection_socket, 1).unwrap();
29 
30     {
31         let (lock, cvar) = &*ready;
32         let mut port = lock.lock().unwrap();
33         *port = who.port();
34         cvar.notify_all();
35     }
36 
37     let mut buffer = vec![0; BUFFER_SIZE];
38     let data_socket = accept(&connection_socket).unwrap();
39     let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
40     assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world");
41 
42     send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap();
43 }
44 
client(ready: Arc<(Mutex<u16>, Condvar)>)45 fn client(ready: Arc<(Mutex<u16>, Condvar)>) {
46     let port = {
47         let (lock, cvar) = &*ready;
48         let mut port = lock.lock().unwrap();
49         while *port == 0 {
50             port = cvar.wait(port).unwrap();
51         }
52         *port
53     };
54 
55     let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port);
56     let mut buffer = vec![0; BUFFER_SIZE];
57 
58     let data_socket = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap();
59     connect_v4(&data_socket, &addr).unwrap();
60 
61     send(&data_socket, b"hello, world", SendFlags::empty()).unwrap();
62 
63     let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
64     assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon");
65 }
66 
67 #[test]
test_v4()68 fn test_v4() {
69     let ready = Arc::new((Mutex::new(0_u16), Condvar::new()));
70     let ready_clone = Arc::clone(&ready);
71 
72     let server = thread::Builder::new()
73         .name("server".to_string())
74         .spawn(move || {
75             server(ready);
76         })
77         .unwrap();
78     let client = thread::Builder::new()
79         .name("client".to_string())
80         .spawn(move || {
81             client(ready_clone);
82         })
83         .unwrap();
84     client.join().unwrap();
85     server.join().unwrap();
86 }
87