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