def sendAck(self): """Function for building and sending acknowledgement frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['ack'], self.seqNo, 'acknowledgement frame') self.recentACK = frame self.connection.send(str.encode(frame.toBinaryString(22)))
def sendAck(self): """Function for building and sending ACK frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['ack'], self.front, 'acknowledgement frame') self.recentACK = frame print("Sent ACK", self.front) self.connection.send(str.encode(frame.toBinaryString(22))) self.lastACKsent = time.time()
def sendFrames(self): """Function to handle data sending""" time.sleep(0.2) # mark the start of sending print("\n", self.name, " starts sending data to ", self.receiver, "\n") # open data file for reading file = open(self.fileName, 'r') # read data from file data_frame = file.read(46) # loop until whole data is sent while data_frame: # if window is not full, send another frame if (self.window_size < MAX_WINDOW_SIZE): # build frame using data, type and sequence number frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['data'], self.end, data_frame) # store current frame for re-transmission (if needed) self.current_window[self.end] = frame # acquire window write lock self.lock.acquire() # send the frame self.connection.send(str.encode(frame.toBinaryString(46))) print("\nSTATUS: FRAME", self.end, "SENT TO CHANNEL") self.frameTimer[self.end] = time.time() # update end, window size and other parameters accordingly self.end = ((self.end + 1) % MAX_SEQUENCE_NUMBER) self.window_size += 1 self.frameCount += 1 self.totalFrameCount += 1 # read next data frame data_frame = file.read(46) # release window write lock self.lock.release() # if all data has been read, break if len(data_frame) == 0: break # set the end-transmitting flag True self.eot = True # close the data file file.close()
def sendFrame(self): """Function to send data""" time.sleep(0.2) # open data file for reading file = open(self.fileName, 'r') # read the first data to be sent in a frame data = file.read(46) self.seqNo = 0 self.frameCount = 0 self.totalframeCount = 0 # loop until whole data is sent while data: if (not self.frameSent): # build frame using data, type and sequence number frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['data'], self.seqNo, data) # store current frame for re-transmission (if needed) self.lastFrame = frame # acquire the send lock self.lock.acquire() # send the frame and start sent-timer self.connection.send(str.encode(frame.toBinaryString(46))) self.sentTime = time.time() self.frameSent = True # update sequence number and other parameters accordingly self.seqNo = (self.seqNo + 1) % 2 self.frameCount += 1 self.totalframeCount += 1 print("\nSTATUS: FRAME", self.frameCount, "SENT TO CHANNEL") # release the send lock self.lock.release() # read next data data = file.read(46) # if all data has been read, break if len(data) == 0: break # set the end of transmission flag to True self.eot = True # close the data file file.close()
def __init__(self, connection, name: str, senderAddress: int, receiverAddress: int, file: str): # get the client/receiver connection and other informations (name, data file name) self.connection = connection self.name = name self.filename = file self.senderAddress = senderAddress self.receiverAddress = receiverAddress # some transmission control variables and flags self.frameType = {'data': 0, 'ack': 1} self.seqNo = 0 self.recentACK = Frame(senderAddress, receiverAddress, 1, 0, "Acknowledgement Frame")
def __init__(self, connection, name: str, senderAddress: int, receiverAddress: int, file: str): # get the client/receiver connection and other informations (name, data file name) self.connection = connection self.name = name self.filename = file self.senderAddress = senderAddress self.receiverAddress = receiverAddress # some transmission control variables and flags self.frameType = {'data': 0, 'ack': 1, 'nak': 2} self.front = 0 self.end = WINDOW_SIZE self.window = [0 for i in range(0, MAX_SEQUENCE_NUMBER)] self.filled_up = [False for i in range(0, MAX_SEQUENCE_NUMBER)] self.nakSent = False self.ackSent = False self.recentACK = Frame(self.senderAddress, self.receiverAddress, 1, 0, "Acknowledgement Frame") self.eot = False self.lastACKsent = None
def startReceiving(self): """# Function for receiving data""" time.sleep(0.4) # receive data from sender data = self.connection.recv(576).decode() # initialise total data received total_data = "" while data != "end": print("\nSTATUS: FRAME RECEIVED") # build frame from binary data string frame = Frame.build(data) # If frame has no error if not frame.hasError(): print("STATUS: NO ERROR FOUND") seqNo = frame.getSeqNo() if self.seqNo == seqNo: # extract data data = frame.getData() # print(data) total_data += data # update the sequence number of ACK self.seqNo = (self.seqNo + 1) % 2 # send the corresponding ACK self.sendAck() print("STATUS: ACK SENT\n") # if sequence number is not what is required, resend the previous ACK else: self.resendPreviousACK() print("STATUS: ACK RESENT") # discard erroneous frame else: print("STATUS: FRAME DISCARDED") # wait and receive next frame data = self.connection.recv(576).decode() file = open(self.filename, 'w') file.write(total_data) file.close()
def receiveAck(self): """Function to handle acknowledgement receiving""" time.sleep(0.2) # loop until end of transmission while (not self.eot) or (self.window_size > 0): # if any frames were sent if (self.window_size > 0): # wait and receive acknowledgement and build frame from that received = self.connection.recv(384).decode() frame = Frame.build(received) else: continue # if frame type is acknowledgement if frame.getType() == 1: # if frame has no error if (frame.hasError() == False): if self.isValidACK(frame.seqNo): # Acquire lock for accessing window self.lock.acquire() # update the window front and window size according to the ackNo while (self.front != frame.seqNo): roundTripTime = time.time() - self.frame_timer[ self.front] rttList.append(roundTripTime) print("STATUS: FRAME", self.front, "HAS REACHED SUCCESSFULLY\n") self.front = (self.front + 1) % (MAX_WINDOW_SIZE + 1) self.window_size -= 1 # Release window access lock self.lock.release() else: print("STATUS: WRONG ACK") else: print("STATUS: ERRONEOUS ACK") else: print("STATUS: RECEIVED FRAME IS NOT AN ACK")
def startReceiving(self): """Function for receiving data""" time.sleep(0.4) # Wait for data and receive data = self.connection.recv(576).decode() total_data = "" # If data-receiving hasn't ended yet while data != "end": # Build frame from binary data string frame = Frame.build(data) print("\nSTATUS: FRAME RECEIVED") # If frame has no error if not frame.hasError(): print("STATUS: NO ERROR FOUND") # get frame sequence number seqNo = frame.getSeqNo() # if the ack no in received frame is equal to the expected if self.seqNo == seqNo: data = frame.getData() # print(data) total_data += data self.seqNo = (self.seqNo + 1) % WINDOW_SIZE self.sendAck() print("STATUS: ACK SENT\n") else: self.resendPreviousACK() print("STATUS: ACK RESENT") # discard erroneous frame else: print("STATUS: FRAME DISCARDED") # wait and receive next frame data = self.connection.recv(576).decode() file = open(self.filename, 'w') file.write(total_data) file.close()
def receiveAck(self): """Function to receive ACK frame""" time.sleep(0.2) # loop until end of transmission while((not self.eot) or (self.frameSent)): # if a frame is sent if self.frameSent: # wait and receive acknowledgement and build frame from that received = self.connection.recv(384).decode() if ("collision" not in received) and len(received) == 384: # decode the received frame frame = Frame.build(received) # if frame type is acknowledgement, do the following if frame.getType() == 1: # if frame has no error, do the following if(frame.hasError()==False): # if ACK_NO == SEQ_NO then receive it, stop timer(set the internal flag of time-out event) if frame.seqNo == self.seqNo: # store the round trip time self.receiveTime = time.time() # evaluate the round trip time and append it to the list roundTripTime = self.receiveTime - self.sentTime rttList.append(roundTripTime) print(self.name, "STATUS: DATA HAS REACHED SUCCESSFULLY\n") # unset the frameSent flag self.frameSent = False else: print(self.name, "STATUS: WRONG ACK") else: print(self.name, "STATUS: ERRONEOUS ACK") else: print(self.name, "STATUS: RECEIVED FRAME IS NOT AN ACK") else: print (self.name, "STATUS: Collision detected") self.collision += 1 self.sentTime=time.time()
class Receiver: def __init__(self, connection, name: str, senderAddress: int, receiverAddress: int, file: str): # get the client/receiver connection and other informations (name, data file name) self.connection = connection self.name = name self.filename = file self.senderAddress = senderAddress self.receiverAddress = receiverAddress # some transmission control variables and flags self.frameType = {'data': 0, 'ack': 1} self.seqNo = 0 self.recentACK = Frame(senderAddress, receiverAddress, 1, 0, "Acknowledgement Frame") def sendAck(self): """Function for building and sending acknowledgement frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['ack'], self.seqNo, 'acknowledgement frame') self.recentACK = frame self.connection.send(str.encode(frame.toBinaryString(22))) def resendPreviousACK(self): """Function for resending previous acknowledgement frame if needed""" self.connection.send(str.encode(self.recentACK.toBinaryString(22))) def startReceiving(self): """# Function for receiving data""" time.sleep(0.4) # receive data from sender data = self.connection.recv(576).decode() # initialise total data received total_data = "" while data != "end": print("\nSTATUS: FRAME RECEIVED") # build frame from binary data string frame = Frame.build(data) # If frame has no error if not frame.hasError(): print("STATUS: NO ERROR FOUND") seqNo = frame.getSeqNo() if self.seqNo == seqNo: # extract data data = frame.getData() # print(data) total_data += data # update the sequence number of ACK self.seqNo = (self.seqNo + 1) % 2 # send the corresponding ACK self.sendAck() print("STATUS: ACK SENT\n") # if sequence number is not what is required, resend the previous ACK else: self.resendPreviousACK() print("STATUS: ACK RESENT") # discard erroneous frame else: print("STATUS: FRAME DISCARDED") # wait and receive next frame data = self.connection.recv(576).decode() file = open(self.filename, 'w') file.write(total_data) file.close()
def receiveAckOrNak(self): """Function to handle acknowledgement receiving""" time.sleep(0.2) # loop until end of transmission while (not self.eot) or (self.window_size > 0): # if any frames were sent if (self.window_size > 0): # wait and receive acknowledgement and build frame from that received = self.connection.recv(384).decode() frame = Frame.build(received) else: continue # if frame type is ACK if frame.getType() == 1: # if frame has no error if (frame.hasError() == False): if self.validACK(frame.seqNo): # Acquire lock for accessing window self.lock.acquire() # update the window front and window size according to the ackNo while (self.front != frame.seqNo): # Store round-trip time into the list roundTripTime = time.time() - self.frameTimer[ self.front] rttList.append(roundTripTime) print("STATUS: FRAME", self.front, "HAS REACHED SUCCESSFULLY\n") self.current_window[self.front] = 0 self.front = ((self.front + 1) % MAX_SEQUENCE_NUMBER) self.window_size -= 1 # release window access lock self.lock.release() else: print("STATUS: WRONG ACK") else: print("STATUS: ERRONEOUS ACK") # if frame type is NAK elif frame.getType() == 2: # if frame has no error if not frame.hasError(): # if requested sequence number is within window if self.validACK(frame.seqNo): # acquire lock for accessing window self.lock.acquire() # resend the requested frame if (self.current_window[frame.seqNo] != 0): self.connection.send( str.encode(self.current_window[ frame.seqNo].toBinaryString(46))) print("STATUS: FRAME", frame.seqNo, "RESENT from NAK") self.frameTimer[frame.seqNo] = time.time() self.totalFrameCount += 1 # release window access lock self.lock.release() else: print("STATUS: WRONG NAK") else: print("STATUS: ERRONEOUS NAK") else: print("STATUS: RECEIVED FRAME IS NOT AN ACK")
def startReceiving(self): """Function for receiving frames""" time.sleep(0.4) ACKresendingThread = threading.Thread(target=self.resendPreviousACK) ACKresendingThread.start() # wait for data and receive data = self.connection.recv(576).decode() total_data = "" while data != "end": # build frame from binary data string frame = Frame.build(data) print("\nSTATUS: FRAME RECEIVED") if not frame.hasError(): print("STATUS: NO ERROR FOUND") seqNo = frame.getSeqNo() # if frame other than first one got, send NAK if (seqNo != self.front and self.nakSent == False): self.sendNak() self.nakSent = True # if seq no within the window accept it if (self.validSEQ(seqNo) and self.filled_up[seqNo] == False): self.filled_up[seqNo] = True self.window[seqNo] = frame.getData() print(frame.getData()) # take the received data sequentially into the final data string # update the front, end of the window accordingly (also update flags) while (self.filled_up[self.front] == True): total_data += self.window[self.front] self.filled_up[self.front] = False self.front = (self.front + 1) % MAX_SEQUENCE_NUMBER self.end = (self.end + 1) % MAX_SEQUENCE_NUMBER self.ackSent = True print("STATUS: FRAME RECEIVED SUCCESSFULLY") # if sequential frame received, send acknowledgement if (self.ackSent): self.sendAck() self.ackSent = False self.nakSent = False # discard erroneous frame else: print("STATUS: ERRONEOUS FRAME") # wait and receive next frame data = self.connection.recv(576).decode() # stop the resending-acknowledgement thread self.eot = True ACKresendingThread.join() # write the whole data into file file = open(self.filename, 'w') file.write(total_data) file.close()
def sendNak(self): """Function for building and sending NAK frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['nak'], self.front, 'not acknowledgement') self.connection.send(str.encode(frame.toBinaryString(22))) print("Sent NAK", self.front)
class Receiver: def __init__(self, connection, name: str, senderAddress: int, receiverAddress: int, file: str): # get the client/receiver connection and other informations (name, data file name) self.connection = connection self.name = name self.filename = file self.senderAddress = senderAddress self.receiverAddress = receiverAddress # some transmission control variables and flags self.frameType = {'data': 0, 'ack': 1, 'nak': 2} self.front = 0 self.end = WINDOW_SIZE self.window = [0 for i in range(0, MAX_SEQUENCE_NUMBER)] self.filled_up = [False for i in range(0, MAX_SEQUENCE_NUMBER)] self.nakSent = False self.ackSent = False self.recentACK = Frame(self.senderAddress, self.receiverAddress, 1, 0, "Acknowledgement Frame") self.eot = False self.lastACKsent = None def validSEQ(self, seq_no: int): """Function to check if the sequence number of incoming frame lies within window""" if ((self.front <= seq_no and seq_no < self.end) or (self.end < self.front and self.front <= seq_no) or (seq_no < self.end and self.end < self.front)): return True else: return False def sendAck(self): """Function for building and sending ACK frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['ack'], self.front, 'acknowledgement frame') self.recentACK = frame print("Sent ACK", self.front) self.connection.send(str.encode(frame.toBinaryString(22))) self.lastACKsent = time.time() def sendNak(self): """Function for building and sending NAK frame""" frame = Frame(self.senderAddress, self.receiverAddress, self.frameType['nak'], self.front, 'not acknowledgement') self.connection.send(str.encode(frame.toBinaryString(22))) print("Sent NAK", self.front) def resendPreviousACK(self): """Function for resending last ACK on timeout""" while (not self.eot): if (self.lastACKsent == None): continue elapsedTime = time.time() - self.lastACKsent if (elapsedTime > 1): self.connection.send( str.encode(self.recentACK.toBinaryString(22))) self.lastACKsent = time.time() def startReceiving(self): """Function for receiving frames""" time.sleep(0.4) ACKresendingThread = threading.Thread(target=self.resendPreviousACK) ACKresendingThread.start() # wait for data and receive data = self.connection.recv(576).decode() total_data = "" while data != "end": # build frame from binary data string frame = Frame.build(data) print("\nSTATUS: FRAME RECEIVED") if not frame.hasError(): print("STATUS: NO ERROR FOUND") seqNo = frame.getSeqNo() # if frame other than first one got, send NAK if (seqNo != self.front and self.nakSent == False): self.sendNak() self.nakSent = True # if seq no within the window accept it if (self.validSEQ(seqNo) and self.filled_up[seqNo] == False): self.filled_up[seqNo] = True self.window[seqNo] = frame.getData() print(frame.getData()) # take the received data sequentially into the final data string # update the front, end of the window accordingly (also update flags) while (self.filled_up[self.front] == True): total_data += self.window[self.front] self.filled_up[self.front] = False self.front = (self.front + 1) % MAX_SEQUENCE_NUMBER self.end = (self.end + 1) % MAX_SEQUENCE_NUMBER self.ackSent = True print("STATUS: FRAME RECEIVED SUCCESSFULLY") # if sequential frame received, send acknowledgement if (self.ackSent): self.sendAck() self.ackSent = False self.nakSent = False # discard erroneous frame else: print("STATUS: ERRONEOUS FRAME") # wait and receive next frame data = self.connection.recv(576).decode() # stop the resending-acknowledgement thread self.eot = True ACKresendingThread.join() # write the whole data into file file = open(self.filename, 'w') file.write(total_data) file.close()