fn send_data(
    config: &Config,
    mut input_file: &mut File,
    socket: &UdpSocket,
    props: &mut SenderConnectionProperties,
    brk: Arc<AtomicBool>,
) -> Result<(), String> {
    // prepare variables
    let mut attempts = 0;
    let mut buffer = vec![0; BUFFER_SIZE];
    // process data
    while attempts < config.repetition && !props.is_complete() && !brk.load(Ordering::SeqCst) {
        // load data to fill rest of the window
        props.load_window(&mut input_file, &config);
        // send data
        props.send_data(&socket, &config);
        // receive response
        let content_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        // process errors for receive
        if let Err(_) = content_result {
            attempts += 1;
            config.vlog(&format!("Recv timeout, increased number of attempts to {}", attempts));
            continue;
        }
        // read received content
        let (recived_len, recived_from) = content_result.unwrap();
        config.vlog(&format!("Received {}b of data from {}", recived_len, recived_from));
        let packet = Packet::from_bin(&buffer[..recived_len], props.static_properties.checksum_size as usize);
        // validate the packet
        let packet = match packet {
            Err(ParsingError::ChecksumNotMatch) => {
                config.vlog("Invalid sum, ignoring");
                continue;
            }
            Err(ParsingError::InvalidFlag(f)) => {
                config.vlog(&format!("Invalid flag {}, ignoring", f));
                continue;
            }
            Err(ParsingError::InvalidSize(expected, actual)) => {
                config.vlog(&format!("Expected {}b but received {}b, ignoring", expected, actual));
                continue;
            }
            Ok(packet) => {
                if packet.header().id != props.static_properties.id {
                    config.vlog("Wrong connection ID, ignoring");
                    continue;
                }
                packet
            }
        };
        // process the packet
        match packet {
            Packet::Init(_) => {
                config.vlog("Init packet received, but connection already established");
                continue;
            }
            Packet::End(_) => {
                config.vlog("End packet received, but hasn't been expected");
                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("Unexpected end packet"));
            }
            Packet::Error(_) => {
                config.vlog("Error packet received");
                println!("Failed because error packet received");
                return Err(String::from("Error packet received"));
            }
            Packet::Data(packet) => {
                if props.acknowledge(packet.header.ack, &config) {
                    attempts = 0;
                }
            }
        };
    };
    // validate whether the loop does not end because of the timeout
    if !props.is_complete() {
        let e = format!("Connection lost after {} attempts or because of termination", attempts);
        config.vlog(&e);
        return Err(e);
    }
    // other end peacefully
    config.vlog("All data send");
    return Ok(());
}
/// Send the data after connection has been established.
/// It send `input_file` file via `socket` using the `props` connection.
Send the data after connection has been established.
Send the data after connection has been established .
fn send_data(
    config: &Config,
    mut input_file: &mut File,
    socket: &UdpSocket,
    props: &mut SenderConnectionProperties,
    brk: Arc<AtomicBool>,
) -> Result<(), String> {
    // prepare variables
    let mut attempts = 0;
    let mut buffer = vec![0; BUFFER_SIZE];
    // process data
    while attempts < config.repetition && !props.is_complete() && !brk.load(Ordering::SeqCst) {
        // load data to fill rest of the window
        props.load_window(&mut input_file, &config);
        // send data
        props.send_data(&socket, &config);
        // receive response
        let content_result = recv_with_timeout(&socket, &mut buffer, Box::new(config));
        // process errors for receive
        if let Err(_) = content_result {
            attempts += 1;
            config.vlog(&format!("Recv timeout, increased number of attempts to {}", attempts));
            continue;
        }
        // read received content
        let (recived_len, recived_from) = content_result.unwrap();
        config.vlog(&format!("Received {}b of data from {}", recived_len, recived_from));
        let packet = Packet::from_bin(&buffer[..recived_len], props.static_properties.checksum_size as usize);
        // validate the packet
        let packet = match packet {
            Err(ParsingError::ChecksumNotMatch) => {
                config.vlog("Invalid sum, ignoring");
                continue;
            }
            Err(ParsingError::InvalidFlag(f)) => {
                config.vlog(&format!("Invalid flag {}, ignoring", f));
                continue;
            }
            Err(ParsingError::InvalidSize(expected, actual)) => {
                config.vlog(&format!("Expected {}b but received {}b, ignoring", expected, actual));
                continue;
            }
            Ok(packet) => {
                if packet.header().id != props.static_properties.id {
                    config.vlog("Wrong connection ID, ignoring");
                    continue;
                }
                packet
            }
        };
        // process the packet
        match packet {
            Packet::Init(_) => {
                config.vlog("Init packet received, but connection already established");
                continue;
            }
            Packet::End(_) => {
                config.vlog("End packet received, but hasn't been expected");
                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("Unexpected end packet"));
            }
            Packet::Error(_) => {
                config.vlog("Error packet received");
                println!("Failed because error packet received");
                return Err(String::from("Error packet received"));
            }
            Packet::Data(packet) => {
                if props.acknowledge(packet.header.ack, &config) {
                    attempts = 0;
                }
            }
        };
    };
    // validate whether the loop does not end because of the timeout
    if !props.is_complete() {
        let e = format!("Connection lost after {} attempts or because of termination", attempts);
        config.vlog(&e);
        return Err(e);
    }
    // other end peacefully
    config.vlog("All data send");
    return Ok(());
}
fn send_data ( config : & Config , mut input_file : & mut File , socket : & UdpSocket , props : & mut SenderConnectionProperties , brk : Arc < AtomicBool > , ) -> Result < ( ) , String > { // prepare variables let mut attempts = 0 ; let mut buffer = vec ! [ 0 BUFFER_SIZE ] ; // process data while attempts < config . repetition && ! props . is_complete ( ) && ! brk . load ( Ordering :: SeqCst ) { // load data to fill rest of the window props . load_window ( & mut input_file , & config ) ; // send data props . send_data ( & socket , & config ) ; // receive response let content_result = recv_with_timeout ( & socket , & mut buffer , Box :: new ( config ) ) ; // process errors for receive if let Err ( _ ) = content_result { attempts += 1 ; config . vlog ( & format ! ( " " attempts ) ) ; continue ; } // read received content let ( recived_len , recived_from ) = content_result . unwrap ( ) ; config . vlog ( & format ! ( " " recived_len recived_from ) ) ; let packet = Packet :: from_bin ( & buffer [ .. recived_len ] , props . static_properties . checksum_size as usize ) ; // validate the packet let packet = match packet { Err ( ParsingError :: ChecksumNotMatch ) => { config . vlog ( " " ) ; continue ; } Err ( ParsingError :: InvalidFlag ( f ) ) => { config . vlog ( & format ! ( " " f ) ) ; continue ; } Err ( ParsingError :: InvalidSize ( expected , actual ) ) => { config . vlog ( & format ! ( " " expected actual ) ) ; continue ; } Ok ( packet ) => { if packet . header ( ) . id != props . static_properties . id { config . vlog ( " " ) ; continue ; } packet } } ; // process the packet match packet { Packet :: Init ( _ ) => { config . vlog ( " " ) ; continue ; } Packet :: End ( _ ) => { 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 ( " " ) ) ; } Packet :: Error ( _ ) => { config . vlog ( " " ) ; println ! ( " " ) ; return Err ( String :: from ( " " ) ) ; } Packet :: Data ( packet ) => { if props . acknowledge ( packet . header . ack , & config ) { attempts = 0 ; } } } ; } ; // validate whether the loop does not end because of the timeout if ! props . is_complete ( ) { let e = format ! ( " " attempts ) ; config . vlog ( & e ) ; return Err ( e ) ; } // other end peacefully config . vlog ( " " ) ; return Ok ( ( ) ) ; }
Send the data after connection has been established.
Send the data after connection has been established .
config
&Config
input_file
&mut File
socket
&UdpSocket
props
&mut SenderConnectionProperties
brk
Arc<AtomicBool>
config
&Config
input_file
&mut File
socket
&UdpSocket
props
&mut SenderConnectionProperties
brk
Arc<AtomicBool>