socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation
use std::net::UdpSocket;
use std::io::Write;
use std::io::Read;
use std::time::Duration;
use std::time::Instant;

use rand::random_range;
use socket9::So9MsgFlags;
use socket9::{Socket9, address::So9DomainInets};


#[test]
fn test_split_simple()
{
    let so9udp = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();

    let (_r, _w) = so9udp.try_split().unwrap();
}

#[test]
fn test_split_simple_unslpit()
{
    let so9udp = Socket9::<UdpSocket>::new_with_bind(&"127.0.0.1:0").unwrap();

    let so9udp_lo = so9udp.local_addr().unwrap();

    let (r, w) = so9udp.try_split().unwrap();

    let so9udp = Socket9::<UdpSocket>::try_unsplit(r, w).unwrap();

    let so9udp_lo2 = so9udp.local_addr().unwrap();

    assert_eq!(so9udp_lo, so9udp_lo2);

    let so9udp_client = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();
    

    let snd_buf: [u8; 4] = [1, 2, 3, 4];
    let snd_n = so9udp_client.send_to(&snd_buf, &so9udp_lo2).unwrap();
    let so9udp_client_addr = so9udp_client.local_addr().unwrap();
    assert_eq!(snd_n, snd_buf.len());

    let mut rcv_buf: [u8; 10] = [0_u8; 10];
    let (rcv_n, rcv_addr) = so9udp.recv_from(&mut rcv_buf, So9MsgFlags::empty()).unwrap();

    assert_eq!(snd_n, rcv_n);
    assert_eq!(so9udp_client_addr.port(), rcv_addr.port());
    assert_eq!(&snd_buf, &rcv_buf[..rcv_n]);
}


#[test]
fn test_split_simple_rw()
{
    let so9udp_serv = Socket9::<UdpSocket>::new_with_bind(&"127.0.0.1:0").unwrap();

    let local_addr = so9udp_serv.local_addr().unwrap();

    let so9udp_cli = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();
    so9udp_cli.connect(local_addr).unwrap();

    let client_addr = so9udp_cli.local_addr().unwrap();

    let (mut r, mut w) = so9udp_cli.try_split().unwrap();

    let snd_buf: [u8; 4] = [1, 2, 3, 4];

    let send_n = w.write(&snd_buf).unwrap();

    assert_eq!(send_n, snd_buf.len());

    let mut rcv_buf: [u8; 10] = [0_u8; 10];

    let (rcv_sn, rcv_client_addr) = so9udp_serv.recv_from(&mut rcv_buf, So9MsgFlags::empty()).unwrap();

    assert_eq!(rcv_sn, send_n);
    assert_eq!(client_addr, rcv_client_addr);
    assert_eq!(&rcv_buf[..rcv_sn], &snd_buf);

    let snd_buf: [u8; 4] = [4, 5, 6, 7];
    let send_n = so9udp_serv.send_to(&snd_buf, &rcv_client_addr).unwrap();
    assert_eq!(send_n, snd_buf.len());

    let mut rcv_buf: [u8; 10] = [0_u8; 10];
    let rcv_n = r.read(&mut rcv_buf).unwrap();

    assert_eq!(rcv_n, send_n);
    assert_eq!(&rcv_buf[..rcv_sn], &snd_buf);

}

#[test]
fn test_split_simple_rw_mt()
{
    let so9udp_serv = Socket9::<UdpSocket>::new_with_bind(&"127.0.0.1:0").unwrap();

    let local_addr = so9udp_serv.local_addr().unwrap();

    let so9udp_cli = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();
    so9udp_cli.connect(local_addr).unwrap();

    let client_addr = so9udp_cli.local_addr().unwrap();

    let (mut r, mut w) = so9udp_cli.try_split().unwrap();

    let snd_buf: [u8; 4] = [4, 5, 6, 7];
    let send_n = so9udp_serv.send_to(&snd_buf, &client_addr).unwrap();
    assert_eq!(send_n, snd_buf.len());

    let ran_dur = Duration::from_nanos(random_range(30..500));
    let now = Instant::now();

    let rcv_thread1 = 
        std::thread::spawn(move ||
            {
                std::thread::sleep(ran_dur);

                let mut rcv_buf: [u8; 10] = [0_u8; 10];
                let rcv_n = r.read(&mut rcv_buf).unwrap();
                let elapsed = now.elapsed();
                println!("received {} bytes", rcv_n);

                assert_eq!(&rcv_buf[..rcv_n], &snd_buf);

                return elapsed;
            }
        );

    let snd_thread2 = 
        std::thread::spawn(move ||
            {
                let snd_buf_thr: [u8; 4] = [1, 2, 3, 4];

                let send_n = w.write(&snd_buf_thr).unwrap();

                assert_eq!(send_n, snd_buf.len());
                let elapsed = now.elapsed();
                println!("sent {} bytes", send_n);

                return elapsed;
            }
        );

    let snd_buf_thr: [u8; 4] = [1, 2, 3, 4];
    let mut rcv_buf: [u8; 10] = [0_u8; 10];
    let (rcv_sn, rcv_client_addr) = so9udp_serv.recv_from(&mut rcv_buf, So9MsgFlags::empty()).unwrap();

    assert_eq!(rcv_sn, send_n);
    assert_eq!(client_addr, rcv_client_addr);
    assert_eq!(&rcv_buf[..rcv_sn], &snd_buf_thr);

    let rcv_el = rcv_thread1.join().unwrap();
    let snd_el = snd_thread2.join().unwrap();

    println!("rcv: {:?} snd: {:?}", rcv_el, snd_el);
}