def send_window_size(server_socket, window_size, client_addr): pkt = packet(data=str(window_size)) server_socket.sendto(pkt.pack(), client_addr) ack, add = server_socket.recvfrom(600) ack_p = packet(pkd_data=ack, type='ack') if ack_p.checksum == calc_checksum(str(window_size)): print('Received file window size ack...')
def get_packets_from_file(file_name): file_bytes = get_bytes_from_file(file_name) file_length = len(file_bytes) seq_count = 0 pkt_list = [] for i in range(0, file_length, 500): if i + 500 > file_length: pkt = packet(seqno=seq_count, data=file_bytes[i:], type='bytes') else: pkt = packet(seqno=seq_count, data=file_bytes[i:i + 500], type='bytes') pkt_list.append(pkt) seq_count += 1 return pkt_list
def recv_window_size(self,socket): pkt, adr = socket.recvfrom(600) unpkd = packet(pkd_data=pkt, type='bytes') ack_p = ack(checksum=calc_checksum(unpkd.data.decode()), seqno=0).pack() socket.send(ack_p) self.window_size = int(unpkd.data) print('Window size = ', self.window_size)
def recv_file_len(self, socket): pkt, adr = socket.recvfrom(600) unpkd = packet(pkd_data=pkt,type='bytes') ack_p = ack(checksum=calc_checksum(unpkd.data.decode()),seqno=0).pack() socket.send(ack_p) self.file_len = int(unpkd.data) print('Required file length = ', self.file_len, ' packets.')
def recv_stop_and_wait(self): client.recv_file_len(self.my_socket) seqno = 0 pkt_num = 0 corrupted = self.get_corrupted_packets(self.file_len,0.05,5) filename = './Clients/'+str(self.server_port)+'/dl_saw_' + str(self.requested_filename) if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) file = open(filename,'wb') while True: received_pack , addr = client.my_socket.recvfrom(600) received_packet = packet(pkd_data=received_pack,type='bytes') if received_packet.seqno in corrupted: received_packet.checksum = received_packet.checksum - 10 corrupted.remove(received_packet.seqno) if(received_packet.checksum==structures.calc_checksum(received_packet.data,type='bytes') and received_packet.seqno==seqno): print(received_packet.data) file.write(received_packet.data) ack_packet = structures.ack(seqno= seqno,checksum=received_packet.checksum) client.my_socket.send(ack_packet.pack()) seqno=(seqno+1)%2 pkt_num += 1 if pkt_num == self.file_len: print('File received.') file.close() break elif(received_packet.seqno!= seqno): client.my_socket.send(ack_packet.pack())
def recv_go_back_n(self): client.recv_file_len(self.my_socket) print('Connected to socket #' + str(self.my_socket.getsockname()[1])) corrupted = self.get_corrupted_packets(self.file_len,0.05,5) exp_pkt_num = 0 while True: try: pkt, adr = self.my_socket.recvfrom(600) recv_pkt = packet(pkd_data=pkt, type='bytes') if recv_pkt.seqno in corrupted: recv_pkt.checksum = recv_pkt.checksum-10 corrupted.remove(recv_pkt.seqno) if adr[0] == self.server_ip: print('Received packet# '+str(recv_pkt.seqno)) # receive packets initally. cs = recv_pkt.checksum ack_pkt= ack(seqno=recv_pkt.seqno, checksum=cs) pkd_ack = ack_pkt.pack() if recv_pkt.seqno == exp_pkt_num and recv_pkt.checksum == calc_checksum(recv_pkt.data, type='bytes'): print('Sending Ack# ' + str(recv_pkt.seqno)) self.recv_pkt_list.append(recv_pkt) # if packets not corrupted and came in order, add to list. self.my_socket.send(pkd_ack) # and send ack exp_pkt_num += 1 else: # else discard packet, will be received again. if recv_pkt.checksum != calc_checksum(recv_pkt.data,type='bytes'): print('Packet # ', recv_pkt.seqno,'is corrupted, re-receiving') continue if self.file_len == len(self.recv_pkt_list): # if all file received, break. print('File received successfully.') break except socket.timeout: print('Packet# ', exp_pkt_num, ' timed out, re-receiving.') continue self.write_file(self.recv_pkt_list)
def send_file_len(socket, address, data): print('Required file: ' + str(data)) req_file = str(data) pkts = get_packets_from_file(req_file) file_len = len(pkts) pkt = packet(seqno=0, data=((str(file_len)).encode()), type='bytes').pack_bytes() socket.sendto(pkt, address) while True: try: ack, add = socket.recvfrom(600) ack_p = packet(pkd_data=ack, type='ack') if ack_p.checksum == calc_checksum(str(file_len)): print('Received file length ack...') break except socket.timeout: continue
def recv_selective_repeat(self): client.recv_file_len(self.my_socket) self.recv_window_size(self.my_socket) window_size = self.window_size #window_size = params[0] packet_number = 0; buffer = "" # divides file content into chunks of packet size next_seqno = 0 send = True file_content = "" pkt_num=0 window = [] window_seqno = [] recv_base = 0 corrupted = self.get_corrupted_packets(self.file_len,0.05,5) filename = './Clients/'+str(self.server_port)+'/dl_sr_' + str(self.requested_filename) if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) file = open(filename,'wb') while True: while (len(window) < window_size): # fills window received_pack, addr = self.my_socket.recvfrom(600) received_packet = packet(pkd_data=received_pack,type='bytes') if received_packet.seqno in corrupted: received_packet.checksum = received_packet.checksum - 10 corrupted.remove(received_packet.seqno) if (received_packet.checksum == structures.calc_checksum( received_packet.data,type='bytes')): ack_packet = structures.ack(seqno=received_packet.seqno, checksum=received_packet.checksum) client.my_socket.send(ack_packet.pack()) if(not (received_packet.seqno in window_seqno)): #print(received_packet.data) window.append(received_packet) window_seqno.append(received_packet.seqno) window = arrange_window(window, recv_base) while (len(window) > 0 and recv_base == window[0].seqno): data =window.pop(0).data print(data) file.write(data) pkt_num += 1 window_seqno.remove(recv_base) recv_base = (recv_base + 1) % window_size if pkt_num == self.file_len: print('File received.') file.close() exit(0)
def stop_and_wait(server_socket, filename, client_addr): send_file_len(server_socket, client_addr, filename) print('Sending using stop and wait.') file_content = readfile(filename) packet_number = 0 seqno = 0 send = True lost_list = lost_packets( len(file_content) // packet_size, probability, random_seed) while (packet_number < len(file_content) / packet_size): if (len(lost_list) > 0 and packet_number == int(lost_list[0])): lost_list.pop(0) send = False if (send): send = False start_index = packet_number * packet_size end_index = packet_number * packet_size + packet_size if (end_index < len(file_content)): buffer = file_content[start_index:end_index] else: buffer = file_content[start_index:] send_packet = structures.packet(seqno=seqno, data=buffer, type='bytes') packed_packet = send_packet.pack_bytes() server_socket.sendto(packed_packet, client_addr) try: ack_pack, addr = server_socket.recvfrom(600) except timeout: send = True #resend continue ack__packet = structures.ack(pkd_data=ack_pack) if (ack__packet.checksum == send_packet.checksum and ack__packet.seqno == seqno): packet_number = packet_number + 1 seqno = (seqno + 1) % 2 send = True
def send_request(self): while True: request_packet = packet(seqno=0, data=self.requested_filename) request_pack = request_packet.pack() self.my_socket.send(request_pack) self.my_socket.settimeout(5) try: rcv, adr = self.my_socket.recvfrom(1024) ack_pkt = ack(pkd_data=rcv) if ack_pkt.checksum == calc_checksum(request_packet.data): print('Request sent..') break else: continue except socket.timeout: print('Request ack timed out.., resending') continue print('File: ' + str(self.requested_filename) + ' has been requested from the server.') self.my_socket.settimeout(None)
def send_requested_file(client_addr, serving_port, filename, algorithm_number=algorithms.stop_and_wait): sending_socket = socket.socket( socket.AF_INET, socket.SOCK_DGRAM) #create new socket for client for sending sending_socket.bind((host, serving_port)) sending_socket.settimeout(time_out) print('Client: ' + str(client_addr[1]) + ' connected... sending file.') # send algorithm used to client to receive according to it. sending_socket.sendto( packet(data=(str(algorithm_number)).encode(), type='bytes').pack_bytes(), client_addr) if algorithm_number == algorithms.selective_repeat: selective_repeat(sending_socket, filename, client_addr) elif algorithm_number == algorithms.go_back_n: go_back_n(filename, sending_socket, client_addr) else: stop_and_wait(sending_socket, filename, client_addr)
def selective_repeat(server_socket, filename, client_addr): print('Sending using selective reapeat.') send_file_len(server_socket, client_addr, filename) send_window_size(server_socket, window_size, client_addr) file_content = readfile(filename) #string containing file content packet_number = 0 # buffer = "" #divides file content into chunks of packet size seqno = 0 send = True lost_list = lost_packets( len(file_content) // packet_size, probability, random_seed) my_threads = [] window = [] received_acks = [] total_packets = len(file_content) / packet_size lock = threading.Lock() send_base = 0 already_acked = [] #seqno not_yet_acked = [] lose = True counter = 0 while True: while (packet_number < total_packets and len(window) < window_size): #fills window start_index = packet_number * packet_size end_index = packet_number * packet_size + packet_size if (end_index < len(file_content)): buffer = file_content[start_index:end_index] else: buffer = file_content[start_index:] send_packet = structures.packet(seqno=seqno, data=buffer, type='bytes') packed_packet = send_packet.pack_bytes() window.append(send_packet) not_yet_acked.append(send_packet) seqno = (seqno + 1) % window_size packet_number = packet_number + 1 not_yet_acked.sort() my_threads = [] for i in window: if (not (i.seqno in already_acked)): if (lose == False or len(lost_list) == 0 or counter != lost_list[0] % window_size): server_socket.sendto(i.pack_bytes(), client_addr) counter = counter + 1 my_threads.append( threading.Thread(target=receive_ack, args=(server_socket, lock, received_acks))) my_threads[-1].start() else: lost_list.pop(0) lose = False for thread in my_threads: thread.join() lose = True my_threads = [] received_acks.sort() i = 0 j = 0 while (len(received_acks) > j and len(not_yet_acked) > i): if (received_acks[j].seqno == not_yet_acked[i].seqno): if (received_acks[j].checksum == not_yet_acked[i].checksum): already_acked.append(received_acks[j].seqno) not_yet_acked.pop(i) j = j + 1 elif (received_acks[j].seqno > not_yet_acked[i].seqno): i = i + 1 else: j = j + 1 already_acked = arrange_seqno(already_acked, send_base) received_acks = [] while (len(already_acked) > 0): if (len(window) > 0 and already_acked[0] == window[0].seqno): window.pop(0) send_base = (already_acked[0] + 1) % window_size already_acked.pop(0) else: break
window_size = int(file.readline()) # in datagrams random_seed = int(file.readline()) probability = float(file.readline()) s.bind((host, port)) # Bind to the port #s.setblocking(1) clients = [] # list of online clients serving_port = 49151 # port used to send the file used_ports = [] # list of ports used to send the file req_err = True while True: print('Waiting for connection... ') request_data, addr = s.recvfrom(1024) # receives packet from clients pkt = packet(pkd_data=request_data) if req_err: req_err = False pkt.checksum = pkt.checksum - 10 if pkt.checksum == calc_checksum(pkt.data): ack_pkt = ack(seqno=0, checksum=calc_checksum(pkt.data)) s.sendto(ack_pkt.pack(), addr) print('File request received, sending ack..') else: print('File request Corrupted..') continue if (addr not in clients): # keep track of clients clients.append(addr) while serving_port in used_ports: # searching for a free port
def resend(my_socket,packet): my_socket.send(packet())
def recv(self, algorithm): recv_call = getattr(self,'recv_'+algorithm) if recv_call: recv_call() else: print("error.. no such algorithm") client = Client('client.in') if len(sys.argv) == 2: client.requested_filename = sys.argv[1] start=time.time() client.send_request() received_pack , addr = client.my_socket.recvfrom(600) received_packet = packet(pkd_data=received_pack) server_new_port = int(received_packet.data) client.server_port = server_new_port print('New port number: ',server_new_port) client.my_socket.connect((client.server_ip,server_new_port)) pkt,adr = client.my_socket.recvfrom(600) pkt = packet(pkd_data=pkt,type='bytes') recv_algo = str(pkt.data.decode()).split('.')[1] print('Receiving using: ',recv_algo) client.recv(recv_algo) client.my_socket.close() end = time.time() time_elapsed = end - start print('Time elapsed= ',time_elapsed) # client.recv_selective_repeat(5)