def est_connection(self): my_syn = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=0, data=b'', ctrl_bits=0x02) packed = my_syn.pkt_pack() self.client_socket.sendto(packed, self.server_addr) try: syn_ack = Packet() recv_data = self.client_socket.recv(self.pkt_size) syn_ack.pkt_unpack(recv_data) if syn_ack.get_ack_bit() and syn_ack.ack_num == 1: self.conn_est = True print("Client: Sending ACK for SYNACK") my_syn = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=1, data=b'', ctrl_bits=0x10) packed = my_syn.pkt_pack() self.client_socket.sendto(packed, self.server_addr) else: print("Client: Connection failed: bad SYNACK") except socket.timeout: print("Client: Connection failed: timeout")
def run(self): """ Runs when Client process has started """ print("Client: Started", flush=True) ack = Packet() ack_data = b'' request = "download" req_pkt = Packet(0, request) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) self.recv_img(self.img_save_to) ack = Packet() ack_data = b'' request = "upload" req_pkt = Packet(0, request) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) self.send_img(self.img_to_send) sleep(5) ack = Packet() ack_data = b'' request = "exit" req_pkt = Packet(0, request) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) print("Client: Exiting...") # close socket when finished self.client_socket.close()
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number # open file to be sent print("Client: Sending image to Server") with open(filename, 'rb') as img: read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() # send data until end of file reached while read_data: self.client_socket.sendto(packed, self.server_addr) #print("Client: Sent:", send_pkt) # wait for ACK recv_data = self.client_socket.recv(self.pkt_size) recv_pkt.pkt_unpack(recv_data) #print("Client: Received message:", recv_pkt) # Received NAK or incorrect ACK if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum(recv_pkt.seq_num, recv_pkt.data): pass # ACK is OK, move to next data and sequence else: #print("Client: got ok packet") seq_num ^= 1 read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack()
def recv_img(self, filename): """ Receive an image packet by packet Saves image to specified file Parameters: filename - file location to save image """ recv_data = b'' # packet of byte string data save_data = b'' # data to be saved to file img_not_recvd = True # flag to indicate if image has been recieved exp_seq = 0 # expected sequence number initially 0 pkt = Packet() self.err_flag = 0 ack = Packet(-1, "ACK") # make initial NAK # get image data from server until all data received while True: try: if img_not_recvd: print("Server: Ready to receive image", flush=True) recv_data = self.server_socket.recv(self.pkt_size) pkt.pkt_unpack(recv_data) if pkt.seq_num != exp_seq or pkt.csum != pkt.checksum( pkt.seq_num, pkt.data): pass else: save_data += pkt.data ack = Packet(exp_seq, "ACK") exp_seq += 1 ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) if img_not_recvd: img_not_recvd = False # img data began streaming if it reaches this point except socket.timeout: # if image not recieved yet, keep waiting if img_not_recvd: pass # image has been recieved else: # write data into a file with open(filename, 'wb+') as server_img: server_img.write(save_data) print("Server: Received and saved image", flush=True) break # exit loop
def est_connection(self, syn_pkt: Packet): self.client_port = syn_pkt.src my_syn = Packet(self.server_port, self.client_port, 0, syn_pkt.ack_num + 1, b'', 0x12) # ack bit = 1, syn bit = 1 packed = my_syn.pkt_pack() self.server_socket.sendto(packed, self.client_addr) try: syn_ack = Packet() recv_data = self.server_socket.recv(self.pkt_size) syn_ack.pkt_unpack(recv_data) if syn_ack.get_ack_bit() and syn_ack.ack_num == 1: self.conn_est = True print("Server: Connection established") else: print("Server: Connection failed: bad SYNACK") except socket.timeout: print("Server: Connection failed: timeout")
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number my_timer = Timer() # Timer thread my_timer.set_time(0.05) # set timer to 50 ms my_timer.stop() # so timer doesn't start counting my_timer.start() # start timer thread # open file to be sent print("Server: Sending image to client") start = time() with open(filename, 'rb') as img: read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() # send data until end of file reached while read_data: if (self.crpt_data_rate > 0 or self.crpt_ack_rate > 0 or self.pkt_loss_rate > 0 or self.ack_loss_rate > 0): self.gen_err_flag() # corrupt 1 byte of the sent packet if self.crpt_data_rate > 0 and self.err_flag <= self.crpt_data_rate: crptpacked = b"".join([packed[0:1023], b"\x00"]) self.server_socket.sendto(crptpacked, self.client_addr) elif self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate: pass # dont send anything else: self.server_socket.sendto(packed, self.client_addr) my_timer.restart() if self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate: while not my_timer.get_exception(): sleep(0.0001) else: # wait for ACK recv_data = self.server_socket.recv(self.pkt_size) if self.ack_loss_rate > 0 and self.err_flag <= self.ack_loss_rate: while not my_timer.get_exception(): sleep(0.0001) else: my_timer.stop() # corrupt 1 byte of the recived ACK packet if self.crpt_ack_rate > 0 and self.err_flag <= self.crpt_ack_rate: recv_data = b"".join([recv_data[0:1023], b"\x00"]) recv_pkt.pkt_unpack(recv_data) # Received NAK or incorrect ACK if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum( recv_pkt.seq_num, recv_pkt.data): pass # ACK is OK, move to next data and sequence else: seq_num ^= 1 read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() my_timer.kill() my_timer.join() end = time() print("Server: Time to send image:", end - start)
def run(self): """ Runs when Server process has started """ print("Server: Started") i = 0 # index of timeouts while True: try: print("Server: Ready", flush=True) # get request and address from client msg = b'' # set message to empty string recv_data = b'' # set received data to empty string msg_pkt = Packet() # init empty packet (recv_data, self.client_addr) = self.server_socket.recvfrom(self.pkt_size) i = 0 # reset timeout index #print("got data") msg_pkt.pkt_unpack(recv_data) #print("Received message:", msg_pkt) if msg_pkt.csum != msg_pkt.checksum(msg_pkt.seq_num, msg_pkt.data): # send NAK nak_seq = msg_pkt.seq_num ^ 0x01 ack = Packet(nak_seq, "ACK") ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) else: msg = msg_pkt.data.decode() print("Server: Client request:", msg, flush=True) except socket.timeout: i = i + 1 if (i < 6): pass # if the server has waited through 6 timeouts (12 seconds), exit else: print("Server: I'm tired of waiting", flush=True) break # if any message recieved, then service it if msg: # ------------------ Send image to client ------------------ if msg == "download": print("Server: Send ACK") ack = Packet(msg_pkt.seq_num, "ACK") #print("ACK:", ack) ack_pack = ack.pkt_pack() #print(int.from_bytes(ack_pack[(len(ack_pack)-2):len(ack_pack)], byteorder='big', signed=False)) self.server_socket.sendto(ack_pack, self.client_addr) # break self.send_img(self.img_to_send) # ------------------ Get image from client ------------------ elif msg == "upload": print("Server: Send ACK") ack = Packet(msg_pkt.seq_num, "ACK") ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) self.recv_img(self.img_save_to) # ------------------ Exit server process ------------------ elif msg == "exit": print("Server: Send ACK") ack = Packet(msg_pkt.seq_num, "ACK") ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) print("Server: Exiting...") break # ------------------ Handle invalid request ------------------ else: # send NAK nak_seq = msg_pkt.seq_num ^ 0x01 ack = Packet(nak_seq, "ACK") ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) print("Server: Received invalid request:", msg) # close socket when finished self.server_socket.close()
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number base = 0 # init base packet number window = [] # init window as empty list win_idx = 0 # index to item in window last_sent = None my_timer = Timer() # Timer thread my_timer.set_time(0.1) # set timer to 100 ms my_timer.stop() # so timer doesn't start counting my_timer.start() # start timer thread self.client_socket.settimeout(0) # don't block when waiting for ACKs # open file to be sent print("Client: Sending image to server") # start = time() with open(filename, 'rb') as img: read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() # add first packet to window list window.append(packed) # send data until end of file reached while read_data or len(window) > 0: if my_timer.get_exception(): self.resend_window(window) my_timer.restart() win_idx = len(window) - 1 if seq_num < (base + self.N) and window[win_idx] != last_sent: self.client_socket.sendto(window[win_idx], self.server_addr) last_sent = window[win_idx] if base == seq_num: my_timer.restart() # start timer seq_num += 1 # wait for ACK if recv_data: recv_data = b'' # empty data buffer try: recv_data = self.client_socket.recv(self.pkt_size) except socket.error as e: if e == 10035: pass if recv_data: recv_pkt.pkt_unpack(recv_data) # Received NAK if recv_pkt.csum != recv_pkt.checksum( recv_pkt.seq_num, recv_pkt.data): pass # ACK is OK else: base = recv_pkt.seq_num + 1 # increment base window.pop(0) # remove acked packet from window if base == seq_num: my_timer.stop() else: my_timer.restart() # Move to next data if len(window) < self.N and read_data: read_data = img.read(self.data_size) # pack send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() window.append(packed) # add packet to window sleep(0.0001) # end = time() my_timer.kill() my_timer.join() self.client_socket.settimeout(5) # reset timeout value
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number snd_crpt_rate = 0 # packet corruption rate in percent crpt_flag = 1 # corruption flag snd_ackcrpt_rate = 0 # recived ACK corruption rate inpercent ackcrpt_flag = 1 # corruption flag for ACK # open file to be sent print("Server: Sending image to client") # start = time() with open(filename, 'rb') as img: read_data = img.read(self.data_size) # send data until end of file reached while read_data: # pack and send send_pkt = Packet(seq_num=seq_num, data=read_data) packed = send_pkt.pkt_pack() # Iteration to corrupt 2 bytes of the sent packet if crpt_flag <= snd_crpt_rate: crptpacked = b"".join([packed[0:1023], b"\x00"]) self.server_socket.sendto(crptpacked, self.client_addr) crpt_flag = crpt_flag + 1 else: crpt_flag = crpt_flag + 1 self.server_socket.sendto(packed, self.client_addr) if crpt_flag > 100: crpt_flag = 1 # wait for ACK recv_data = self.server_socket.recv(self.pkt_size) # Iteration to corrupt 2 bytes of the recived ACK packet if ackcrpt_flag <= snd_ackcrpt_rate: recv_data = b"".join([recv_data[0:1023], b"\x00"]) ackcrpt_flag = ackcrpt_flag + 1 else: ackcrpt_flag = ackcrpt_flag + 1 if ackcrpt_flag > 100: ackcrpt_flag = 1 recv_pkt.pkt_unpack(recv_data) # Received NAK or incorrect ACK if recv_pkt.seq_num != seq_num or recv_pkt.csum != recv_pkt.checksum( recv_pkt.seq_num, recv_pkt.data): pass # ACK is OK, move to next data and sequence else: seq_num ^= 1 read_data = img.read(self.data_size)
def run(self): """ Runs when Client process has started """ print("Client: Started", flush=True) ack = Packet() ack_data = b'' self.est_connection() request = "download" req_pkt = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=0, data=request, ctrl_bits=0x00) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) self.recv_img(self.img_save_to) """ ack = Packet() ack_data = b'' request = "upload" req_pkt = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=0, data=request, ctrl_bits=0x00) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) self.send_img(self.img_to_send) sleep(5) """ ack = Packet() ack_data = b'' request = "exit" req_pkt = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=0, data=request, ctrl_bits=0x01) req_packed = req_pkt.pkt_pack() self.client_socket.sendto(req_packed, self.server_addr) ack_data = self.client_socket.recv(self.pkt_size) ack.pkt_unpack(ack_data) fin = Packet() fin_data = self.client_socket.recv(self.pkt_size) fin.pkt_unpack(fin_data) ack = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=0, data=b'', ctrl_bits=0x10) ack_pack = ack.pkt_pack() self.client_socket.sendto(ack_pack, self.server_addr) print("Client: Connection closed") print("Client: Exiting...") # close socket when finished self.client_socket.close()
def recv_img(self, filename): """ Receive an image packet by packet Saves image to specified file Parameters: filename - file location to save image """ recv_data = b'' # packet of byte string data save_data = b'' # data to be saved to file img_not_recvd = True # flag to indicate if image data hasn't started yet exp_seq = 0 # expected sequence number initially 0 chunks = {} # init dictionary of received data chunks pkt = Packet() # get image data from server until all data received while True: try: if (self.crpt_ack_rate > 0 or self.ack_loss_rate > 0): self.gen_err_flag() if img_not_recvd: print("Client: Ready to receive image", flush=True) recv_data = self.client_socket.recv(self.pkt_size) pkt.pkt_unpack(recv_data) if pkt.seq_num < exp_seq or pkt.csum != pkt.checksum(): pass elif pkt.seq_num > exp_seq: if pkt.seq_num not in chunks.keys(): chunks[pkt.seq_num] = pkt.data else: chunks[pkt.seq_num] = pkt.data # increment expected sequence to highest received data exp_seq += len(pkt.data) while exp_seq in chunks.keys(): exp_seq += len(chunks[exp_seq]) ack = Packet(src=self.client_port, dst=self.server_port, seq_num=0, ack_num=exp_seq, data=b'', ctrl_bits=0x10) ack_pack = ack.pkt_pack() if (self.ack_loss_rate > 0 and self.err_flag <= self.ack_loss_rate): pass elif (self.crpt_ack_rate > 0 and self.err_flag <= self.crpt_ack_rate): ack_pack = b"".join([ack_pack[0:1023], b"\x01"]) self.client_socket.sendto(ack_pack, self.server_addr) else: self.client_socket.sendto(ack_pack, self.server_addr) if img_not_recvd: img_not_recvd = False # img data began streaming if it reaches this point except socket.timeout: # if image not recieved yet, keep waiting if img_not_recvd: pass # image has been recieved else: break # exit loop for chunk in sorted(chunks.keys()): save_data += chunks[chunk] # write data into a file with open(filename, 'wb+') as client_img: client_img.write(save_data) print("Client: Received and saved image", flush=True)
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number base = 0 # init base packet number window = {} # init window as empty dict dupl_cnt = 0 # count of duplicate acks my_timer = Timer() # Timer thread my_timer.set_time(0.1) # set timer to 100 ms my_timer.stop() # so timer doesn't start counting my_timer.start() # start timer thread rtt_start = {} self.client_socket.settimeout(0) # don't block when waiting for ACKs # open file to be sent print("Client: Sending image to server") # start = time() with open(filename, 'rb') as img: read_data = img.read(self.data_size) # pack send_pkt = Packet(src=self.client_port, dst=self.server_port, seq_num=seq_num, ack_num=0, data=read_data, ctrl_bits=0x00) next_pkt = send_pkt.pkt_pack() # add first packet to window list window[send_pkt.seq_num] = next_pkt # send data until all data acked while read_data or len(window) > 0: # Move to next data if len(window) < self.N and read_data: read_data = img.read(self.data_size) # pack if read_data: send_pkt = Packet(src=self.client_port, dst=self.server_port, seq_num=seq_num, ack_num=0, data=read_data, ctrl_bits=0x00) next_pkt = send_pkt.pkt_pack() window[send_pkt. seq_num] = next_pkt # add packet to window else: # no more data to be sent next_pkt = None if next_pkt: self.client_socket.sendto(next_pkt, self.server_addr) next_pkt = None rtt_start[send_pkt.seq_num] = time() if base == seq_num: my_timer.restart() # start timer seq_num += len(send_pkt.data) if my_timer.get_exception(): self.N = ceil(self.N / 2) self.resend_lost(window, base) rtt_start[base] = time() my_timer.restart() # receive ACK if recv_data: recv_data = b'' # empty data buffer try: recv_data = self.client_socket.recv(self.pkt_size) except socket.error as e: if e == 10035: pass if recv_data: recv_pkt.pkt_unpack(recv_data) if recv_pkt.csum != recv_pkt.checksum(): pass # ACK is OK else: rtt_end = time() if recv_pkt.ack_num > base: dupl_cnt = 0 # reset duplicate count prev_base = base base = recv_pkt.ack_num # increment base for pkt in sorted(window.keys( )): # remove acked packets from window if pkt < base: window.pop(pkt) else: break if len(window) == 0: # no unacked packets my_timer.stop() else: # unacked packets remaining my_timer.restart( self.est_timeout(rtt_end - rtt_start[prev_base])) self.N += 1 elif recv_pkt.ack_num == base: dupl_cnt += 1 # received 3 duplicate ACKs if dupl_cnt >= 3: dupl_cnt = 0 self.N = ceil(self.N / 2) self.resend_lost(window, base) rtt_start[base] = time() my_timer.restart() sleep(0.0001) # end = time() my_timer.kill() my_timer.join() self.N = 1 #reset window size self.est_rtt = 0.1 # reset estimated rtt self.dev_rtt = 0 # reset deviation self.client_socket.settimeout(1) # reset timeout value
def send_img(self, filename): """ Sends the image packet by packet Parameters: filename - file to send """ recv_data = b'' # bytes for data received recv_pkt = Packet() # init empty packet for received data read_data = b'' # byte string data read from file seq_num = 0 # init sequence number base = 0 # init base packet number window = {} # init window as empty dictionary dupl_cnt = 0 # count of duplicate acks my_timer = Timer() # Timer thread my_timer.set_time(0.1) # set timer to 100 ms my_timer.stop() # so timer doesn't start counting my_timer.start() # start timer thread rtt_start = {} window_list = [] rtt_list = [] new_timeout = 0.1 self.server_socket.settimeout(0) # don't block when waiting for ACKs # open file to be sent print("Server: Sending image to client") start = time() with open(filename, 'rb') as img: read_data = img.read(self.data_size) # pack send_pkt = Packet(src=self.server_port, dst=self.client_port, seq_num=seq_num, ack_num=0, data=read_data, ctrl_bits=0x00) next_pkt = send_pkt.pkt_pack() # add first packet to window list window[send_pkt.seq_num] = next_pkt # send data until all data acked while read_data or len(window) > 0: if (self.crpt_data_rate > 0 or self.pkt_loss_rate > 0): self.gen_err_flag() window_list.append(self.N) rtt_list.append(new_timeout) # Move to next data if len(window) < self.N and read_data: read_data = img.read(self.data_size) # pack if read_data: send_pkt = Packet(src=self.server_port, dst=self.client_port, seq_num=seq_num, ack_num=0, data=read_data, ctrl_bits=0x00) next_pkt = send_pkt.pkt_pack() window[send_pkt. seq_num] = next_pkt # add packet to window else: # no more data to be sent next_pkt = None if next_pkt: if self.crpt_data_rate > 0 and self.err_flag <= self.crpt_data_rate: # corrupt 1 byte of the sent packet crptpacked = b"".join([next_pkt[0:1023], b"\x00"]) self.server_socket.sendto(crptpacked, self.client_addr) elif self.pkt_loss_rate > 0 and self.err_flag <= self.pkt_loss_rate: pass # dont send anything else: # send normally self.server_socket.sendto(next_pkt, self.client_addr) next_pkt = None rtt_start[send_pkt.seq_num] = time() if base == seq_num: my_timer.restart() # start timer seq_num += len(send_pkt.data) if my_timer.get_exception(): self.N = ceil(self.N / 2) self.resend_lost(window, base) rtt_start[base] = time() my_timer.restart() # receive ACK if recv_data: recv_data = b'' # empty data buffer try: recv_data = self.server_socket.recv(self.pkt_size) except socket.error as e: if e == 10035: pass if recv_data: recv_pkt.pkt_unpack(recv_data) # Received NAK if recv_pkt.csum != recv_pkt.checksum(): pass # ACK is OK else: rtt_end = time() if recv_pkt.ack_num > base: dupl_cnt = 0 # reset duplicate count prev_base = base base = recv_pkt.ack_num # increment base for pkt in sorted(window.keys( )): # remove acked packets from window if pkt < base: window.pop(pkt) else: break if len(window) == 0: # no unacked packets my_timer.stop() else: # unacked packets remaining new_timeout = rtt_end - rtt_start[prev_base] my_timer.restart(self.est_timeout(new_timeout)) self.N += 1 elif recv_pkt.ack_num == base: dupl_cnt += 1 # received 3 duplicate ACKs if dupl_cnt >= 3: dupl_cnt = 0 self.N = ceil(self.N / 2) self.resend_lost(window, base) rtt_start[base] = time() my_timer.restart() sleep(0.0001) end = time() my_timer.kill() my_timer.join() with open("window_size.csv", 'w+', newline='') as win_csv: writer = csv.writer(win_csv, delimiter=',') writer.writerow(window_list) with open("rtt_times.csv", 'w+', newline='') as rtt_csv: writer = csv.writer(rtt_csv, delimiter=',') writer.writerow(rtt_list) self.N = 1 #reset window size self.est_rtt = 0.1 # reset estimated rtt self.dev_rtt = 0 # reset deviation self.server_socket.settimeout(5) # reset timeout value print("Server: Time to send image:", end - start)
def run(self): """ Runs when Server process has started """ print("Server: Started") i = 0 # index of timeouts while True: try: print("Server: Ready", flush=True) # get request and address from client msg = b'' # set message to empty string recv_data = b'' # set received data to empty string msg_pkt = Packet() # init empty packet (recv_data, self.client_addr) = self.server_socket.recvfrom(self.pkt_size) i = 0 # reset timeout index msg_pkt.pkt_unpack(recv_data) if msg_pkt.get_syn_bit(): print("Server: Client request: Pls let me connect", flush=True) else: msg = msg_pkt.data.decode() print("Server: Client request:", msg, flush=True) except socket.timeout: i = i + 1 if (i < 6): pass # if the server has waited through 6 timeouts (30 seconds), exit else: print("Server: I'm tired of waiting", flush=True) break if self.conn_est: # if any message recieved, then service it # ------------------ Send image to client ------------------ if msg == "download": ack = Packet(self.server_port, self.client_port, 0, msg_pkt.ack_num + 1, b'', 0x10) ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) # break self.send_img(self.img_to_send) # ------------------ Get image from client ------------------ elif msg == "upload": ack = Packet(self.server_port, self.client_port, 0, msg_pkt.ack_num + 1, b'', 0x10) ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) self.recv_img(self.img_save_to) # ------------------ Exit server process ------------------ elif msg == "exit": ack = Packet(self.server_port, self.client_port, 0, msg_pkt.ack_num + 1, b'', 0x10) ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) # send FIN packet fin = Packet(self.server_port, self.client_port, 0, 0, b'', 0x01) fin_pack = fin.pkt_pack() self.server_socket.sendto(fin_pack, self.client_addr) fin_ack = Packet() recv_data = self.server_socket.recv(self.pkt_size) fin_ack.pkt_unpack(recv_data) if fin_ack.get_ack_bit: print("Server: Connection closed") print("Server: Exiting...") break else: print("Server: Connection teardown failed") # ------------------ Handle invalid request ------------------ else: # send NAK ack = Packet(self.server_port, self.client_port, 0, 0, b'', 0x10) ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) print("Server: Received invalid request:", msg_pkt) # break elif msg_pkt.get_syn_bit and not self.conn_est: print("Server: Establishing Connection...") self.est_connection(msg_pkt) else: print("Server: Connection not established yet") # send NAK ack = Packet(self.server_port, self.client_port, 0, 0, b'', 0x10) ack_pack = ack.pkt_pack() self.server_socket.sendto(ack_pack, self.client_addr) # close socket when finished self.server_socket.close()