fn create_connection(
    config: &Config,
    socket: &UdpSocket,
    addr: SocketAddr,
    brk: Arc<AtomicBool>,
) -> Result<SenderConnectionProperties, ()> {
    // create buffer
    let mut buffer = vec![0; BUFFER_SIZE];
    // create my init packet
    let mut init_packet = InitPacket::new(
        config.window_size,
        config.packet_size,
        config.checksum_size,
    );

    // for specified number of retries
    let mut attempts = 0;
    while attempts < config.repetition && !brk.load(Ordering::SeqCst) {
        // send packet
        config.vlog(&format!("Attempt {} to establish connection", attempts + 1));
        let packet = Packet::from(Clone::clone(&init_packet));
        let wrote = packet.to_bin_buff(&mut buffer, init_packet.checksum_size as usize);
        socket.send_to(&buffer[..wrote], addr).expect("Can't send data and establish connection");
        config.vlog(&format!(
            "Init packet send - packet size: {}, checksum size: {}, window_size: {}",
            init_packet.packet_size,
            init_packet.checksum_size,
            init_packet.window_size
        ));
        // wait for answer
        let recv_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        if let Err(_) = recv_result {
            attempts += 1;
            continue;
        };
        // get raw data
        let (data_size, received_from) = recv_result.unwrap();
        config.vlog(&format!("Received {} data from {}", data_size, received_from));
        if data_size < PacketHeader::bin_size() {
            config.vlog("Received less data than header, ignoring");
            attempts += 1;
            continue;
        }
        // parse init packet without exception
        let init_content_result = InitPacket::from_bin_no_size_and_hash_check(&buffer[..data_size]);
        if let Err(e) = init_content_result {
            config.vlog(&format!("Can't read init content of the packet {:?}", e));
            continue;
        }
        let init_content = init_content_result.unwrap();
        // parse packet itself
        let packet_result = Packet::from_bin(&buffer[..data_size], init_content.checksum_size as usize);
        // decide what to do with the packet
        match packet_result {
            Ok(Packet::Init(packet)) => {
                init_packet.packet_size = min(init_packet.packet_size, packet.packet_size);
                init_packet.window_size = min(init_packet.window_size, packet.window_size);
                init_packet.checksum_size = max(init_packet.checksum_size, packet.checksum_size);
                if packet.header.id == 0 {
                    config.vlog("Received init packet with 0 id, receiver couldn't receive whole packet, repeating");
                    continue;
                }
                let props = SenderConnectionProperties::new(ConnectionProperties::new(
                    packet.header.id,
                    init_packet.checksum_size,
                    init_packet.window_size,
                    init_packet.packet_size,
                    received_from,
                ));
                config.vlog(&format!("Connection {} established, window_size: {}, packet_size: {}, checksum_size: {}",
                                     props.static_properties.id,
                                     props.static_properties.window_size,
                                     props.static_properties.packet_size,
                                     props.static_properties.checksum_size));
                return Ok(props);
            }
            Ok(_) => {
                config.vlog("Not init packet received, dropping");
            }
            Err(ParsingError::InvalidSize(expected, actual)) => {
                init_packet.packet_size = actual as u16;
                config.vlog(&format!("Expected to received {} bytes, but {} only received, repeating with new configuration", expected, actual));
                continue;
            }
            Err(e) => {
                config.vlog(&format!("Packet can't be parsed: {:?}", e));
                continue;
            }
        };
    }
    // didn't receive init packet after specified number of retries
    println!("Can't establish connection with the server after {} attempts", config.repetition);
    return Err(());
}
/// Connect to the receiver and agree on the connection properties.
/// It uses `socket` and expect receiver at the `addr` address.
Connect to the receiver and agree on the connection properties.
It uses `socket` and expect receiver at the `addr` address.
Connect to the receiver and agree on the connection properties . It uses ` socket ` and expect receiver at the ` addr ` address .
fn create_connection(
    config: &Config,
    socket: &UdpSocket,
    addr: SocketAddr,
    brk: Arc<AtomicBool>,
) -> Result<SenderConnectionProperties, ()> {
    // create buffer
    let mut buffer = vec![0; BUFFER_SIZE];
    // create my init packet
    let mut init_packet = InitPacket::new(
        config.window_size,
        config.packet_size,
        config.checksum_size,
    );
    // for specified number of retries
    let mut attempts = 0;
    while attempts < config.repetition && !brk.load(Ordering::SeqCst) {
        // send packet
        config.vlog(&format!("Attempt {} to establish connection", attempts + 1));
        let packet = Packet::from(Clone::clone(&init_packet));
        let wrote = packet.to_bin_buff(&mut buffer, init_packet.checksum_size as usize);
        socket.send_to(&buffer[..wrote], addr).expect("Can't send data and establish connection");
        config.vlog(&format!(
            "Init packet send - packet size: {}, checksum size: {}, window_size: {}",
            init_packet.packet_size,
            init_packet.checksum_size,
            init_packet.window_size
        ));
        // wait for answer
        let recv_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        if let Err(_) = recv_result {
            attempts += 1;
            continue;
        };
        // get raw data
        let (data_size, received_from) = recv_result.unwrap();
        config.vlog(&format!("Received {} data from {}", data_size, received_from));
        if data_size < PacketHeader::bin_size() {
            config.vlog("Received less data than header, ignoring");
            attempts += 1;
            continue;
        }
        // parse init packet without exception
        let init_content_result = InitPacket::from_bin_no_size_and_hash_check(&buffer[..data_size]);
        if let Err(e) = init_content_result {
            config.vlog(&format!("Can't read init content of the packet {:?}", e));
            continue;
        }
        let init_content = init_content_result.unwrap();
        // parse packet itself
        let packet_result = Packet::from_bin(&buffer[..data_size], init_content.checksum_size as usize);
        // decide what to do with the packet
        match packet_result {
            Ok(Packet::Init(packet)) => {
                init_packet.packet_size = min(init_packet.packet_size, packet.packet_size);
                init_packet.window_size = min(init_packet.window_size, packet.window_size);
                init_packet.checksum_size = max(init_packet.checksum_size, packet.checksum_size);
                if packet.header.id == 0 {
                    config.vlog("Received init packet with 0 id, receiver couldn't receive whole packet, repeating");
                    continue;
                }
                let props = SenderConnectionProperties::new(ConnectionProperties::new(
                    packet.header.id,
                    init_packet.checksum_size,
                    init_packet.window_size,
                    init_packet.packet_size,
                    received_from,
                ));
                config.vlog(&format!("Connection {} established, window_size: {}, packet_size: {}, checksum_size: {}",
                                     props.static_properties.id,
                                     props.static_properties.window_size,
                                     props.static_properties.packet_size,
                                     props.static_properties.checksum_size));
                return Ok(props);
            }
            Ok(_) => {
                config.vlog("Not init packet received, dropping");
            }
            Err(ParsingError::InvalidSize(expected, actual)) => {
                init_packet.packet_size = actual as u16;
                config.vlog(&format!("Expected to received {} bytes, but {} only received, repeating with new configuration", expected, actual));
                continue;
            }
            Err(e) => {
                config.vlog(&format!("Packet can't be parsed: {:?}", e));
                continue;
            }
        };
    }
    // didn't receive init packet after specified number of retries
    println!("Can't establish connection with the server after {} attempts", config.repetition);
    return Err(());
}
fn create_connection ( config : & Config , socket : & UdpSocket , addr : SocketAddr , brk : Arc < AtomicBool > , ) -> Result < SenderConnectionProperties , ( ) > { // create buffer let mut buffer = vec ! [ 0 BUFFER_SIZE ] ; // create my init packet let mut init_packet = InitPacket :: new ( config . window_size , config . packet_size , config . checksum_size , ) ; // for specified number of retries let mut attempts = 0 ; while attempts < config . repetition && ! brk . load ( Ordering :: SeqCst ) { // send packet config . vlog ( & format ! ( " " attempts 1 ) ) ; let packet = Packet :: from ( Clone :: clone ( & init_packet ) ) ; let wrote = packet . to_bin_buff ( & mut buffer , init_packet . checksum_size as usize ) ; socket . send_to ( & buffer [ .. wrote ] , addr ) . expect ( " " ) ; config . vlog ( & format ! ( " " init_packet packet_size init_packet checksum_size init_packet window_size ) ) ; // wait for answer let recv_result = recv_with_timeout ( & socket , & mut buffer , Box :: new ( config ) ) ; if let Err ( _ ) = recv_result { attempts += 1 ; continue ; } ; // get raw data let ( data_size , received_from ) = recv_result . unwrap ( ) ; config . vlog ( & format ! ( " " data_size received_from ) ) ; if data_size < PacketHeader :: bin_size ( ) { config . vlog ( " " ) ; attempts += 1 ; continue ; } // parse init packet without exception let init_content_result = InitPacket :: from_bin_no_size_and_hash_check ( & buffer [ .. data_size ] ) ; if let Err ( e ) = init_content_result { config . vlog ( & format ! ( " " e ) ) ; continue ; } let init_content = init_content_result . unwrap ( ) ; // parse packet itself let packet_result = Packet :: from_bin ( & buffer [ .. data_size ] , init_content . checksum_size as usize ) ; // decide what to do with the packet match packet_result { Ok ( Packet :: Init ( packet ) ) => { init_packet . packet_size = min ( init_packet . packet_size , packet . packet_size ) ; init_packet . window_size = min ( init_packet . window_size , packet . window_size ) ; init_packet . checksum_size = max ( init_packet . checksum_size , packet . checksum_size ) ; if packet . header . id == 0 { config . vlog ( " " ) ; continue ; } let props = SenderConnectionProperties :: new ( ConnectionProperties :: new ( packet . header . id , init_packet . checksum_size , init_packet . window_size , init_packet . packet_size , received_from , ) ) ; config . vlog ( & format ! ( " " props static_properties id props static_properties window_size props static_properties packet_size props static_properties checksum_size ) ) ; return Ok ( props ) ; } Ok ( _ ) => { config . vlog ( " " ) ; } Err ( ParsingError :: InvalidSize ( expected , actual ) ) => { init_packet . packet_size = actual as u16 ; config . vlog ( & format ! ( " " expected actual ) ) ; continue ; } Err ( e ) => { config . vlog ( & format ! ( " " e ) ) ; continue ; } } ; } // didn't receive init packet after specified number of retries println ! ( " " config repetition ) ; return Err ( ( ) ) ; }
Connect to the receiver and agree on the connection properties.
Connect to the receiver and agree on the connection properties .
config
&Config
socket
&UdpSocket
addr
SocketAddr
brk
Arc<AtomicBool>
config
&Config
socket
&UdpSocket
addr
SocketAddr
brk
Arc<AtomicBool>