def rdt_rcv(sock):
    data = extract(sock)

    if data == 0:
        return None

    # parse packets
    ACK = data[0:4]
    rec_seq = data[4:20]
    rec_cksum = rdt_utils.parse_checksum(data[20:])

    # Handle error possibilities
    if rdt_utils.has_ack_bit_err(
    ) and rdt_utils.random_channel() < config.percent_corrupt:
        corruptData = rdt_utils.corrupt_bits(ACK)
        calc = corruptData + rec_seq
    elif rdt_utils.has_ack_packet_loss(
    ) and rdt_utils.random_channel() < config.percent_corrupt:
        rdt_utils.debug_print(f"ACK Packet #{int(rec_seq, 2)} Dropped !")
        return None
    else:
        calc = ACK + rec_seq
    checksum = rdt_utils.calc_checksum(calc)

    if rec_cksum != checksum:
        rdt_utils.debug_print(
            f"Bit error encountered in ACK #{int(rec_seq, 2)}!")
        return None

    rdt_utils.debug_print(
        f'ACK Packet #{int(rec_seq, 2)} successfully received')

    return int(rec_seq, 2)
Exemple #2
0
def rdt_rcv(sock, seqNum):
    data = extract(sock)

    if data == 0:
        return 0

    # parse packets
    ACK = data[0:4]
    recSeq = data[4:5]
    rec_cksum = rdt_utils.parse_checksum(data[5:])

    if rdt_utils.has_ack_bit_err(
    ) and rdt_utils.random_channel() < config.percent_corrupt:
        if config.debug:
            print("Bit error encountered in ACK!")
        corruptData = rdt_utils.corrupt_bits(ACK)
        calc = corruptData + recSeq
    elif rdt_utils.has_ack_packet_loss(
    ) and rdt_utils.random_channel() < config.percent_corrupt:
        if config.debug:
            print("ACK Packet Dropped!")
        return 0
    else:
        calc = ACK + recSeq
    checksum = rdt_utils.calc_checksum(calc)

    return ACK == b'1111' and recSeq == seqNum and rec_cksum == checksum
Exemple #3
0
def rdt_rcv(fname, sock):
    expected_seq_num = 0
    expected_seq_num_b = rdt_utils.seq_num_to_bin(expected_seq_num)
    ACK = bin(15)[2:].encode('utf-8')

    oncethru = False
    endpoint = None  # Endpoint starts off unitialized, get it from first received packet
    f = None  # Don't open file until know that we received message
    sndpkt = None
    while True:
        pkt, addr = extract(sock)
        # Initialize endpoint with actual addr received
        if not endpoint and addr:
            endpoint = addr
        # Got actual message
        if pkt and addr:
            # Open file if not opened
            if not f:
                f = open(fname, 'wb')
            #parse packet
            rec_seq = pkt[0:16]
            rec_ck = rdt_utils.parse_checksum(pkt[16:18])
            data = pkt[18:]

            if rdt_utils.has_data_bit_err(
            ) and rdt_utils.random_channel() < config.percent_corrupt:
                if config.debug:
                    print("Bit error encountered in Data!")
                corruptData = rdt_utils.corrupt_bits(data)
                calc = rec_seq + corruptData
            else:
                calc = rec_seq + data

            chksum = rdt_utils.calc_checksum(calc)

            # correct sequence number
            if (not config.loss_recovery
                    or expected_seq_num_b == rec_seq) and chksum == rec_ck:
                deliver_data(f, data)
                sndpkt = make_pkt(ACK, rec_seq)
                udt_send(sndpkt, endpoint, sock)

                expected_seq_num += 1
                expected_seq_num_b = rdt_utils.seq_num_to_bin(expected_seq_num)
            else:
                # didn't receive right pkt, either seqnum wrong or cksum
                if config.debug:
                    print("Bad data received, sending prev ACK")
                if oncethru and sndpkt:
                    udt_send(sndpkt, endpoint, sock)
        else:
            # Close file if opened
            if f:
                f.close()
            break
        oncethru = True
    return endpoint
def rdt_rcv(file, endpoint, sock):
    oncethru = 0
    seqNum = 0
    seq = bin(seqNum)[2:].encode("utf-8")
    ACK = bin(15)[2:].encode('utf-8')

    while True:
        pkt = extract(sock)
        if pkt:
            #parse packet
            recSeq = pkt[0:1]
            rec_ck = rdt_utils.parse_checksum(pkt[1:3])
            data = pkt[3:]

            if rdt_utils.has_data_bit_err(
            ) and rdt_utils.random_channel() < config.percent_corrupt:
                if config.debug:
                    print("Bit error encountered in Data!")
                corruptData = rdt_utils.corrupt_bits(data)
                calc = recSeq + corruptData
            else:
                calc = recSeq + data

            chksum = rdt_utils.calc_checksum(calc)

            # correct sequence number
            if seq == recSeq and chksum == rec_ck:
                deliver_data(file, data)
                sndpkt = make_pkt(ACK, recSeq, chksum)
                udt_send(sndpkt, endpoint, sock)

                # switch sequence number
                if seqNum == 0:
                    seqNum = 1
                else:
                    seqNum = 0
                seq = bin(seqNum)[2:].encode("utf-8")
                oncethru = 1
            else:
                # didn't receive right pkt, either seqnum wrong or cksum
                if oncethru == 1:
                    if config.debug:
                        print("Bad data received, sending prev ACK")
                    udt_send(sndpkt, endpoint, sock)
                else:
                    if config.debug:
                        print("Bad data received in first packet")
        else:
            file.close()
            break
Exemple #5
0
def rdt_send(file, endpoint, sock):
    timer = rdt_utils.RDTTimer(config.timeout)

    # Returns callback function for when timeout reached
    def timeout_func(packet, endpoint, sock):
        def ret_func():
            if config.debug:
                print("Timeout for ACK exceeded, resending packet")
            udt_send(packet, endpoint, sock)
            # Forget last timer and start new one
            timer.start(timeout_func(packet, endpoint, sock))

        return ret_func

    seqNum = 0
    seq = bin(seqNum)[2:].encode("utf-8")
    packet = make_pkt(file, seq)

    while packet != 0:
        if rdt_utils.has_data_packet_loss(
        ) and rdt_utils.random_channel() < config.percent_corrupt:
            if config.debug:
                print("DATA Packet Dropped!")
        else:
            udt_send(packet, endpoint, sock)
        timer.start(timeout_func(packet, endpoint, sock))
        while not rdt_rcv(sock, seq):
            pass
        timer.cancel()
        if seqNum == 0:  # switch sequence numbers
            seqNum = 1
        else:
            seqNum = 0
        seq = bin(seqNum)[2:].encode("utf-8")
        packet = make_pkt(file, seq)
        time.sleep(0.005)
def udt_send(packet, endpoint, sock, packet_num):
    if rdt_utils.has_data_packet_loss(
    ) and rdt_utils.random_channel() < config.percent_corrupt:
        rdt_utils.debug_print(f'DATA Packet #{packet_num} Dropped!')
        return
    return sock.sendto(packet, endpoint)
def udt_send(packet, endpoint, sock):
    if rdt_utils.has_data_packet_loss() and rdt_utils.random_channel() < config.percent_corrupt:
            if config.debug:
                print("DATA Packet Dropped!")
            return
    return sock.sendto(packet, endpoint)
def rdt_rcv(fname, sock):
    rcv_buf = rdt_utils.RCVPacketBuffer(config.max_buf_size,
                                        config.window_size)
    ACK = bin(15)[2:].encode('utf-8')

    endpoint = None  # Endpoint starts off unitialized, get it from first received packet
    f = None  # Don't open file until know that we received message
    sndpkt = None
    while True:
        pkt, addr = extract(sock)
        # Initialize endpoint with actual addr received
        if not endpoint and addr:
            endpoint = addr
        # Got actual message
        if pkt and addr:
            # Open file if not opened
            if not f:
                f = open(fname, 'wb')
            #parse packet
            rec_seq = pkt[0:16]
            rec_ck = rdt_utils.parse_checksum(pkt[16:18])
            data = pkt[18:]

            if rdt_utils.has_data_bit_err(
            ) and rdt_utils.random_channel() < config.percent_corrupt:
                corruptData = rdt_utils.corrupt_bits(data)
                calc = rec_seq + corruptData
            else:
                calc = rec_seq + data

            chksum = rdt_utils.calc_checksum(calc)

            rec_seq_int = int(rec_seq, 2)
            if chksum == rec_ck:
                sndpkt = make_pkt(ACK, rec_seq)
                if rcv_buf.includes(rec_seq_int):
                    udt_send(sndpkt, endpoint, sock)
                    rcv_buf.buf[rec_seq_int] = data
                    rdt_utils.debug_print(
                        f'Data packet #{int(rec_seq, 2)} added to receive buffer'
                    )
                    # Inorder
                    if rec_seq_int == rcv_buf.base:
                        while rcv_buf.buf[rcv_buf.base] is not None:
                            deliver_data(f, rcv_buf.buf[rcv_buf.base])
                            rdt_utils.debug_print(
                                f'Data {rcv_buf.base} delivered to file')
                            rcv_buf.base += 1
                elif rec_seq_int < rcv_buf.base:
                    udt_send(sndpkt, endpoint, sock)
            else:
                # didn't receive right pkt, wrong cksum
                rdt_utils.debug_print(
                    f'Bit error encountered in data packet #{int(rec_seq, 2)}, doing nothing'
                )
        else:
            # Close file if opened
            if f:
                f.close()
            break
    return endpoint