xref: /third_party/rust/crates/rustix/tests/net/v4.rs (revision b8a62b91)
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