fn send_end(
    config: &Config,
    socket: &UdpSocket,
    props: &mut SenderConnectionProperties,
    brk: Arc<AtomicBool>,
) -> Result<(), String> {
    // creates variables
    let mut buffer = vec![0; BUFFER_SIZE];
    let packet = Packet::from(EndPacket::new(
        props.static_properties.id,
        props.window_position,
    ));
    // wait for end packet
    let mut attempts = 0;
    while attempts < config.repetition && !brk.load(Ordering::SeqCst) {
        // send end packet
        let size = packet.to_bin_buff(&mut buffer, props.static_properties.checksum_size as usize);
        socket.send_to(&buffer[..size], props.static_properties.socket_addr).expect("Can't send end packet");
        config.vlog("Send end packet");
        // receive response
        let recv_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        if let Err(_) = recv_result {
            attempts += 1;
            continue;
        }
        let (recv_size, _) = recv_result.unwrap();
        // parse packet
        let packet = Packet::from_bin(&buffer[..recv_size], props.static_properties.checksum_size as usize);
        if let Err(e) = packet {
            config.vlog(&format!("Error parsing end packet {:?}", e));
            continue;
        }
        let packet = packet.unwrap();
        // make sure it is packet for this connection
        if packet.header().id != props.static_properties.id {
            config.vlog("Receive packet with invalid connection number");
            if Flag::Init == packet.header().flag {
                continue; // init flag delay on the way with not established connection
            }
            return Err(String::from("Received packet with invalid connection number"));
        }
        // handle end packet
        match packet {
            // it is end packet as expected
            Packet::End(packet) => {
                // if the end packet is invalid send error and terminate
                if packet.header.ack != props.window_position || packet.header.seq != props.window_position {
                    config.vlog("Received invalid end packet");
                    let error_packet = ErrorPacket::new(props.static_properties.id);
                    let answer_length = Packet::from(error_packet).to_bin_buff(&mut buffer, props.static_properties.checksum_size as usize);
                    socket.send_to(&buffer[..answer_length], config.send_addr()).expect("Can't send error packet");
                    return Err(String::from("Invalid end packet"));
                }
                // else end peacefully
                println!("File receive confirmed");
                return Ok(());
            }
            // error on the receiver part, ending
            Packet::Error(_) => {
                config.vlog("Received error packet instead of end packet");
                return Err(String::from("Error packet received"));
            }
            // data or init packet delayed on the way, ignoring
            _ => {
                config.vlog("Received data or init packet after sending end packet, ignoring");
                continue;
            }
        };
    }
    return Err(String::from("End packet timeout or terminatioln"));
}
/// Ends the connection after the file has been received.
/// It sends data using `socket` and closes connection specified by `props`.
Ends the connection after the file has been received.
It sends data using `socket` and closes connection specified by `props`.
Ends the connection after the file has been received . It sends data using ` socket ` and closes connection specified by ` props ` .
fn send_end(
    config: &Config,
    socket: &UdpSocket,
    props: &mut SenderConnectionProperties,
    brk: Arc<AtomicBool>,
) -> Result<(), String> {
    // creates variables
    let mut buffer = vec![0; BUFFER_SIZE];
    let packet = Packet::from(EndPacket::new(
        props.static_properties.id,
        props.window_position,
    ));
    // wait for end packet
    let mut attempts = 0;
    while attempts < config.repetition && !brk.load(Ordering::SeqCst) {
        // send end packet
        let size = packet.to_bin_buff(&mut buffer, props.static_properties.checksum_size as usize);
        socket.send_to(&buffer[..size], props.static_properties.socket_addr).expect("Can't send end packet");
        config.vlog("Send end packet");
        // receive response
        let recv_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        if let Err(_) = recv_result {
            attempts += 1;
            continue;
        }
        let (recv_size, _) = recv_result.unwrap();
        // parse packet
        let packet = Packet::from_bin(&buffer[..recv_size], props.static_properties.checksum_size as usize);
        if let Err(e) = packet {
            config.vlog(&format!("Error parsing end packet {:?}", e));
            continue;
        }
        let packet = packet.unwrap();
        // make sure it is packet for this connection
        if packet.header().id != props.static_properties.id {
            config.vlog("Receive packet with invalid connection number");
            if Flag::Init == packet.header().flag {
                continue; // init flag delay on the way with not established connection
            }
            return Err(String::from("Received packet with invalid connection number"));
        }
        // handle end packet
        match packet {
            // it is end packet as expected
            Packet::End(packet) => {
                // if the end packet is invalid send error and terminate
                if packet.header.ack != props.window_position || packet.header.seq != props.window_position {
                    config.vlog("Received invalid end packet");
                    let error_packet = ErrorPacket::new(props.static_properties.id);
                    let answer_length = Packet::from(error_packet).to_bin_buff(&mut buffer, props.static_properties.checksum_size as usize);
                    socket.send_to(&buffer[..answer_length], config.send_addr()).expect("Can't send error packet");
                    return Err(String::from("Invalid end packet"));
                }
                // else end peacefully
                println!("File receive confirmed");
                return Ok(());
            }
            // error on the receiver part, ending
            Packet::Error(_) => {
                config.vlog("Received error packet instead of end packet");
                return Err(String::from("Error packet received"));
            }
            // data or init packet delayed on the way, ignoring
            _ => {
                config.vlog("Received data or init packet after sending end packet, ignoring");
                continue;
            }
        };
    }
    return Err(String::from("End packet timeout or terminatioln"));
}
fn send_end ( config : & Config , socket : & UdpSocket , props : & mut SenderConnectionProperties , brk : Arc < AtomicBool > , ) -> Result < ( ) , String > { // creates variables let mut buffer = vec ! [ 0 BUFFER_SIZE ] ; let packet = Packet :: from ( EndPacket :: new ( props . static_properties . id , props . window_position , ) ) ; // wait for end packet let mut attempts = 0 ; while attempts < config . repetition && ! brk . load ( Ordering :: SeqCst ) { // send end packet let size = packet . to_bin_buff ( & mut buffer , props . static_properties . checksum_size as usize ) ; socket . send_to ( & buffer [ .. size ] , props . static_properties . socket_addr ) . expect ( " " ) ; config . vlog ( " " ) ; // receive response let recv_result = recv_with_timeout ( & socket , & mut buffer , Box :: new ( config ) ) ; if let Err ( _ ) = recv_result { attempts += 1 ; continue ; } let ( recv_size , _ ) = recv_result . unwrap ( ) ; // parse packet let packet = Packet :: from_bin ( & buffer [ .. recv_size ] , props . static_properties . checksum_size as usize ) ; if let Err ( e ) = packet { config . vlog ( & format ! ( " " e ) ) ; continue ; } let packet = packet . unwrap ( ) ; // make sure it is packet for this connection if packet . header ( ) . id != props . static_properties . id { config . vlog ( " " ) ; if Flag :: Init == packet . header ( ) . flag { continue ; // init flag delay on the way with not established connection } return Err ( String :: from ( " " ) ) ; } // handle end packet match packet { // it is end packet as expected Packet :: End ( packet ) => { // if the end packet is invalid send error and terminate if packet . header . ack != props . window_position || packet . header . seq != props . window_position { config . vlog ( " " ) ; let error_packet = ErrorPacket :: new ( props . static_properties . id ) ; let answer_length = Packet :: from ( error_packet ) . to_bin_buff ( & mut buffer , props . static_properties . checksum_size as usize ) ; socket . send_to ( & buffer [ .. answer_length ] , config . send_addr ( ) ) . expect ( " " ) ; return Err ( String :: from ( " " ) ) ; } // else end peacefully println ! ( " " ) ; return Ok ( ( ) ) ; } // error on the receiver part, ending Packet :: Error ( _ ) => { config . vlog ( " " ) ; return Err ( String :: from ( " " ) ) ; } // data or init packet delayed on the way, ignoring _ => { config . vlog ( " " ) ; continue ; } } ; } return Err ( String :: from ( " " ) ) ; }
Ends the connection after the file has been received.
Ends the connection after the file has been received .
config
&Config
socket
&UdpSocket
props
&mut SenderConnectionProperties
brk
Arc<AtomicBool>
config
&Config
socket
&UdpSocket
props
&mut SenderConnectionProperties
brk
Arc<AtomicBool>