def receive(sock): global mutex global base global send_timer while True: pkt, _ = udt.recv(sock) ack_pack = packet.my_unpack(pkt) """ - Actualizar la base - Detener el timer - Recuerde utilizar mutex para las actualizaciones """ # print('Got ACK', ack_pack.ack) if (ack_pack.ack >= base): mutex.acquire() base = ack_pack.ack + 1 # print('Base updated', base) send_timer.stop() mutex.release() if not send_timer.running(): break mutex.acquire() if end_conn_timer: mutex.release() raise Exception('WAITING TIME EXCEDED')
def send_syn(conn, address): seq_num = randint(1, 99) ack = randint(1, 99) conn.dest_host, conn.dest_port = utils.parse_address(address) pack = packet.create_syn_packet(conn.port, conn.dest_port, seq_num, ack, conn.host, conn.dest_host) conn.socket.sendto(pack, (conn.dest_host, conn.dest_port)) pack = packet.my_unpack(pack) return pack
def wait_confirm(conn, synack_pack): global mutex global send_timer timer = Timer(TIMEOUT_INTERVAL) threading.Thread(target=timer_send_pack, args=(conn, synack_pack, timer)).start() synack_pack = packet.my_unpack(synack_pack) send_timer.start() threading.Thread(target=countdown, args=(END_CONN_INTERVAL,)).start() while True: conf_pack, _ = conn.socket.recvfrom(1024) conf_pack = packet.my_unpack(conf_pack) if conf_pack.check_checksum(): print('checksum error') continue if conf_pack.is_ack() and conf_pack.seq_num == synack_pack.ack: mutex.acquire() send_timer.stop() mutex.release() return conf_pack
def wait_syn(conn): while True: syn_pack, _ = conn.socket.recvfrom(1024) syn_pack = packet.my_unpack(syn_pack) if syn_pack.check_checksum(): print('checksum error') continue conn.dest_host = syn_pack.source_ip conn.dest_port = syn_pack.source_port if syn_pack.is_syn(): synack_pack = packet.create_synack_packet(syn_pack) conn.socket.sendto(synack_pack, (syn_pack.source_ip, syn_pack.source_port)) return synack_pack
def wait_close(conn, close_pack): global mutex global send_timer timer = Timer(TIMEOUT_INTERVAL - 1) conn.socket.sendto(close_pack, (conn.dest_host, conn.dest_port)) threading.Thread(target=timer_send_pack, args=(conn, close_pack, timer)).start() send_timer.start() threading.Thread(target=countdown, args=(END_CONN_INTERVAL, 'CONNECTION CLOSED WITHOUT CONFIRMATION')).start() while True: tup = udt.recv(conn.socket) close_pack = packet.my_unpack(tup[0]) if close_pack.is_end(): mutex.acquire() send_timer.stop() mutex.release() return close_pack
def update_variables(pack, data): global WINDOW_SIZE global PACK_SIZE global CURRENT_PACK global BASE global UPPER_BASE global LEN_DATA global seq_num global ack seq_num += 1 ack += 1 CURRENT_PACK += 1 if CURRENT_PACK == UPPER_BASE: BASE = UPPER_BASE UPPER_BASE = min(UPPER_BASE + WINDOW_SIZE, UPPER_BASE + (LEN_DATA - UPPER_BASE)) pack = packet.my_unpack(pack) PACK_SIZE = min(PACK_SIZE, pack.data_len)
def receive(conn, data): threading.Thread(target=countdown, args=(END_CONN_INTERVAL, )).start() sock = conn.socket expected_num = conn.seq_num + 1 recv_packets = [] while True: # Get the next packet from the sender pack, addr = udt.recv(sock) pack = packet.my_unpack(pack) # if not pack.check_checksum(): # print('check error') # continue # print('Got packet', pack.seq_num) # print(pack.data) if pack.is_end(): close_pack = packet.create_close_packet(conn) udt.send(close_pack, sock, addr) # print('CONNECTION CLOSED') return recv_packets # Send back an ACK if pack.seq_num == expected_num: # print('Got expected packet') recv_packets.append(pack) # print('Sending ACK', expected_num) ack_pack = packet.create_ack_packet(conn, expected_num) udt.send(ack_pack, sock, addr) expected_num += 1 # if pack.is_last_pack(): # print("last pack received") # return recv_packets else: # print('Sending ACK', expected_num - 1) ack_pack = packet.create_ack_packet(conn, expected_num - 1) udt.send(ack_pack, sock, addr) return recv_packets
def wait_synack(conn, syn_pack): global mutex global send_timer timer = Timer(TIMEOUT_INTERVAL) flags = packet.create_flags(False, True) syn_packed = syn_pack.pack(flags) threading.Thread(target=timer_send_pack, args=(conn, syn_packed, timer)).start() send_timer.start() threading.Thread(target=countdown, args=(END_CONN_INTERVAL,)).start() while True: synack_pack, _ = conn.socket.recvfrom(1024) synack_pack = packet.my_unpack(synack_pack) if synack_pack.check_checksum(): continue if synack_pack.is_syn() and synack_pack.is_ack() and synack_pack.seq_num == syn_pack.ack and synack_pack.source_ip == syn_pack.dest_ip and synack_pack.source_port == syn_pack.dest_port: mutex.acquire() send_timer.stop() mutex.release() return synack_pack
def send_confirmation(conn, synack_pack): conf_pack = packet.create_confirmation_packet(synack_pack) conn.socket.sendto(conf_pack, (conn.dest_host, conn.dest_port)) conf_pack = packet.my_unpack(conf_pack) return conf_pack
def send(conn, data): global mutex global base global send_timer sock = conn.socket RECEIVER_ADDR = (conn.dest_ip, conn.dest_port) packets = create_pack_list(conn, data) num_packets = len(packets) window_size = set_window_size(num_packets) next_to_send = 0 base = 0 # Start the receiver thread threading.Thread(target=receive, args=(sock, )).start() threading.Thread(target=countdown, args=(END_CONN_INTERVAL, )).start() while base < num_packets: """ - Enviar los mensajes en la ventana - Esperar mientras no se reciba el ACK - Reenviar los mensajes desde la base si da timeout - Recuerde utilizar mutex para las actualizaciones de base y send_timer - Use SLEEP_INTERVAL mientras espera recibir el ACK """ mutex.acquire() # Send all the packets in the window while next_to_send < base + window_size: # print('Sending packet', next_to_send) unpacked = packet.my_unpack(packets[next_to_send]) udt.send(packets[next_to_send], sock, RECEIVER_ADDR) next_to_send += 1 # Start the timer if not send_timer.running(): # print('Starting timer') send_timer.start() # Wait until a timer goes off or we get an ACK while send_timer.running() and not send_timer.timeout(): mutex.release() # print('Sleeping') time.sleep(SLEEP_INTERVAL) mutex.acquire() if send_timer.timeout(): # Looks like we timed out # print('Timeout') send_timer.stop() next_to_send = base else: # print('Shifting window') window_size = set_window_size(num_packets) if end_conn_timer: mutex.release() raise Exception('WAITING TIME EXCEDED') mutex.release() print('last pack sent')