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 7use rustix::net::{ 8 accept, bind_v4, connect_v4, getsockname, listen, recv, send, socket, AddressFamily, Ipv4Addr, 9 Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, SocketType, 10}; 11use std::sync::{Arc, Condvar, Mutex}; 12use std::thread; 13 14const BUFFER_SIZE: usize = 20; 15 16fn 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 45fn 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] 68fn 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