Question: Please go through the code for reliable transport provided below and fix it as per the requirements of the test. Please leave the updated code
Please go through the code for reliable transport provided below and fix it as per the requirements of the test. Please leave the updated code in the answer below.
Both the ReliableMessageSender and ReliableMessageReceiver classes in reliable_transport.py have already been implemented. The code runs the following tests:
Testing BasicFunctionality
Test Failed: Client output is not correct file: client3: test_file1
Testing PacketLoss
Test Failed: Client output is not correct file: client1: test_file2
Testing DuplicatePackets
Test Failed: Client output is not correct file: client1: test_file2
Testing OutOfOrderPackets
Test Failed: Client output is not correct file: client1: test_file2
Testing WindowSize
Test Failed! More packets are in flight than window_size
The implementation of the code is as follows:
from queue import Queue
from typing import Tuple
from socket import socket
import util
import time
import operator
# from reliable_socket import ReliableSocket
Address = Tuple[str, int]
class MessageSender:
'''
DO NOT EDIT ANYTHING IN THIS CLASS
'''
def __init__(self, sock: socket, receiver_addr: Address, msg_id: int):
self.__sock: socket = sock
self.__receiver_addr = receiver_addr
self.__msg_id = msg_id
def send(self, packet: str):
self.__sock.sendto(
(f"s:{str(self.__msg_id)}:{packet}").encode("utf-8"),
self.__receiver_addr)
class ReliableMessageSender(MessageSender):
def __init__(self, sock: socket, receiver_addr: Address, msg_id: int,
window_size: int):
MessageSender.__init__(self, sock, receiver_addr, msg_id)
self.queue_acknowledgement = Queue();
self.seqno = 0
self.packets = []
self.waitingForAck = set()
self.messageReceived = False
self.window_size = window_size
self.timeout = False
def waitForAck(self):
while True:
if not self.queue_acknowledgement.empty():
seq_num = self.queue_acknowledgement.get()
if int(seq_num) == self.seqno:
self.packets = self.packets[self.window_size:]
break
elif int(seq_num) > self.seqno:
self.packets = self.packets[int(seq_num) - self.seqno]
self.seqno = int(seq_num)
break
elif self.timeout:
self.timeout = False
break
else:
self.timeout = True
for packet in self.packets:
self.send(packet)
def on_packet_received(self, packet: str):
if not util.validate_checksum(packet):
print("Packet is invalid")
return
else:
packet_type, sequence_number, packet_data, packet_checksum = util.parse_packet(packet)
if packet_type=="ack":
self.queue_acknowledgement.put(sequence_number)
def send_message(self, message: str):
''''
TO BE IMPLEMENTED BY STUDENTS
This method reliably sends the passed message to the receiver
'''
startPacket = util.make_packet("start",self.seqno)
self.send(startPacket)
print(startPacket)
self.packets.append(startPacket)
try:
startCheck = self.queue_acknowledgement.get(timeout=util.TIME_OUT)
print("start seqno: ", startCheck )
except:
self.send(startPacket)
packetData = [message[i:i+util.CHUNK_SIZE] for i in range(0,len(message), util.CHUNK_SIZE)]
for chunks in packetData:
self.seqno = self.seqno+1
print("While sending data seqno: ", self.seqno)
data_packet = util.make_packet("data",self.seqno,chunks)
self.packets.append(data_packet)
self.send(data_packet)
print(data_packet)
if len(self.packets) >= self.window_size:
self.waitForAck()
if self.timeout:
continue
self.seqno+=1
print("end seq no.: ", self.seqno)
end_packet = util.make_packet("end",self.seqno)
print(end_packet)
self.send(end_packet)
self.packets.append(end_packet)
try:
endCheck = self.queue_acknowledgement.get(timeout=util.TIME_OUT)
except:
self.send(util.make_packet("end",self.seqno))
return
class MessageReceiver:
'''
DO NOT EDIT ANYTHING IN THIS CLASS
'''
def __init__(self, sock: socket, sender_addr: Address, msg_id: int,
completed_message_q: Queue):
self.__sock: socket = sock
self.__sender_addr = sender_addr
self.__msg_id = msg_id
self.__completed_message_q = completed_message_q
def send(self, packet: str):
self.__sock.sendto(
(f"r:{str(self.__msg_id)}:{packet}").encode("utf-8"),
self.__sender_addr)
def on_message_completed(self, message: str):
self.__completed_message_q.put(message)
class ReliableMessageReceiver(MessageReceiver):
'''
This class reliably receives a message from a sender.
You have to implement the on_packet_received method
'''
def __init__(self, sock: socket, sender_addr: Address, msg_id: int,
completed_message_q: Queue):
MessageReceiver.__init__(self, sock, sender_addr, msg_id,
completed_message_q)
'''
This is the constructor of the class where you can define any class attributes to maintain state.
You should immediately return from this function and not block.
'''
self.packet_data_list = []
self.seqnoExpected = 1
self.message = ""
def on_packet_received(self, packet: str):
# packet_type, sequence_number, packet_data, packet_checksum = util.parse_packet(packet)
if not util.validate_checksum(packet):
print("Packet not received on receiver side")
return
elif util.validate_checksum(packet):
packet_type, sequence_number, packet_data, packet_checksum = util.parse_packet(packet)
if packet_type=="start":
print("receiver side start seqno: ", sequence_number)
self.seqnoExpected = int(sequence_number)+1
elif packet_type=="data" and int(sequence_number)==self.seqnoExpected:
self.seqnoExpected = int(sequence_number) + 1
self.message+=packet_data
if not any(dataseqno == self.seqnoExpected and msg_content==self.message for dataseqno,msg_content in self.packet_data_list):
self.packet_data_list.append((self.seqnoExpected,self.message))
self.packet_data_list.sort(key=operator.itemgetter(0))
self.send(util.make_packet("ack",self.seqnoExpected))
elif packet_type=="end" and int(sequence_number)==self.seqnoExpected:
self.on_message_completed(self.message)
self.seqnoExpected = int(sequence_number)+1
self.send(util.make_packet("ack",self.seqnoExpected))
self.packet_data_list.clear()
Update this code in python.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
