def close_tcp_connection(self, pkt_fin): pkt = make_pkt(4322, pkt_fin['seq_number'] + len_pkt(pkt_fin), self.client_id, ACK=1) self.send_pkt(pkt) pkt = make_pkt(connection_id=self.client_id, FIN=1) self.send_pkt(pkt)
def send_file(self): len_archive = popen("du -hsb " + self.filename).read().split("\t")[0] print(len_archive) print(self.filename) self.file = open(self.filename, "rb") self.send_initial_pkt() count_part = 512 while (True): self.recv_ack_pkt() if (self.window.can_send_pkt()): text = self.file.read(512) count_part += len(text) if (not text): break pkt = make_pkt(self.seq_num, connection_id=self.id, data=text) self.send_pkt(pkt) pkt = unpack(pkt) self.window.buff.append(pkt) if (self.window.base_equal_next_seq_num()): pass self.update_window() self.file.close()
def send_pkt_syn_ack(self): pkt = make_pkt(seq_number=self.seq_num, ack_number=self.ack_num, connection_id=self.client_id, SYN=1, ACK=1) self.send_pkt(pkt)
def send_initial_pkt(self): text = self.file.read(512) pkt = make_pkt(self.seq_num, self.ack_num, self.id, ACK=1, data=text) self.send_pkt(pkt) pkt = unpack(pkt) self.window.buff.append(pkt) self.update_window()
def run( self ): try: self.conn = socket( AF_INET, SOCK_DGRAM ) self.conn.setsockopt( SOL_SOCKET, SO_REUSEADDR, 1) self.conn.bind( ( "", self.udp_port ) ) self.send_pkt_syn_ack() file = open( self.file_dir + str( self.client_id ) + ".file" ,"wb" ) while( not self.close_connection.is_set() ): self.conn.settimeout(10) data, _ = self.conn.recvfrom( 524 ) if not data: self.error(file) continue else: self.conn.settimeout(None) print("[<==] ",end=" ") show_pkt(data) pkt = unpack( data ) if( pkt['FIN'] ): file.close() self.close_tcp_connection( pkt ) self.close_connection.set() break else: self.clear_buff( pkt ) if( self.duplicate_ack( pkt ) ): make_pkt(self.data_to_send_acks[-1]) self.send_pkt( self.data_to_send_acks[-1] ) else: # self.window.buff.append( pkt ) file.write( pkt['data'] ) self.seq_num = pkt['ack_number'] self.ack_num = pkt['seq_number'] + len_pkt( pkt ) pkt = make_pkt(seq_number=self.seq_num, ack_number=self.ack_num, connection_id=self.client_id, ACK=1) self.send_pkt( pkt ) pkt = unpack( pkt ) self.data_to_send_acks.append( pkt ) except: self.close()
def close(self): pkt = make_pkt(self.seq_num, self.ack_num, connection_id=self.id, FIN=1) self.send_pkt(pkt) pkt = unpack(pkt) self.window.buff.append(pkt) self.wait_ack_of_fin() self.wait_for_fin() print("d Number of duplicate packages :", self.c_duplicate_pkt)
def recv_ack_pkt(self): # print( self.window ) def duplicate_ack(pkt): if (self.recved_acks.count(pkt['ack_number']) == 4): return True return False def index_pkt_ack(pkt): for i, p in enumerate(self.window.buff): if (pkt['ACK'] and is_ack_of(pkt, p)): self.recved_acks.append(p['ack_number']) return i + 1 # self.conn.settimeout( 0.1 ) # try: data, _ = self.conn.recvfrom(524) # except: # self.c_rtrss_pkt += 1 # self.conn.settimeout(None) if (self.c_rtrss_pkt == 5): print('===== Start retranmission') for p in self.window.buff[self.window.base:self.window. next_seq_num]: pkt = make_pkt(p['seq_number'], p['ack_number'], p['connection_id'], data=p['data']) self.send_pkt(pkt) #print( "[<==] ",end=" ") #show_pkt(data) pkt = unpack(data) index = index_pkt_ack(pkt) if (index): if (duplicate_ack(pkt)): self.resend_pkt(index + 1) self.window.ssthresh = self.window.size * 512 // 2 self.window.set_default() self.c_duplicate_pkt += 1 else: self.window.base = index if (self.window.size * 512 < self.window.ssthresh): self.window.size *= 2 else: self.window.size += 1
def send_file(self): def print_parts_file(number_parts, len_total): system("clear") print("d Sending file...") aux = "#" * number_parts aux2 = " " * (len_total - number_parts) print("[" + aux + aux2 + "]") len_archive = popen("du -hsb " + self.filename).read().split("\t")[0] print(len_archive) print(self.filename) len_part = int(len_archive) // 60 self.file = open(self.filename, "rb") self.send_initial_pkt() count_part = 512 while (True): self.recv_ack_pkt() if (self.window.can_send_pkt()): text = self.file.read(512) count_part += len(text) print_parts_file(count_part // len_part, int(len_archive) // len_part) if (not text): break pkt = make_pkt(self.seq_num, connection_id=self.id, data=text) self.send_pkt(pkt) pkt = unpack(pkt) self.window.buff.append(pkt) if (self.window.base_equal_next_seq_num()): # start_time() pass self.update_window() self.file.close()
def send_pkt_syn(self): pkt = make_pkt(seq_number=self.seq_num, connection_id=self.id, SYN=1) self.send_pkt(pkt)
def send_pkt_ack_for_fin(self, pkt): self.window.buff.append(pkt) self.update_window() n_pkt = make_pkt(self.seq_num, self.ack_num, self.id, ACK=1) self.send_pkt(n_pkt)