From 4b06b2f9b358f32adce16be48b65cab77bed708a Mon Sep 17 00:00:00 2001 From: kejingfan Date: Wed, 3 Apr 2024 01:56:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90lab3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Labs/Lab3/src/Receiver.py | 58 +++++++++++++++++++ Labs/Lab3/src/Sender.py | 115 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 Labs/Lab3/src/Receiver.py create mode 100644 Labs/Lab3/src/Sender.py diff --git a/Labs/Lab3/src/Receiver.py b/Labs/Lab3/src/Receiver.py new file mode 100644 index 0000000..2f0d965 --- /dev/null +++ b/Labs/Lab3/src/Receiver.py @@ -0,0 +1,58 @@ +import socket +import random + +class NetworkLayer: + def __init__(self, host="0.0.0.0", port=31415) -> None: + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.connect((host, port)) + + def udt_send(self, data:str): + self.socket.send(data.encode()) + + def udt_rcv(self) -> str: + while True: + message = self.socket.recv(1024).decode("utf-8") + return message + + + +class ApplicationLayer: + def __init__(self) -> None: + self.data = list() + + +class Receiver: + def __init__(self, networkLayer:NetworkLayer, applicationLayer:ApplicationLayer): + self.expected_seq_num = 0 + self.networkLayer = networkLayer + self.applicationLayer = applicationLayer + + def deliver_data(self, data, seq_num): + if seq_num == self.expected_seq_num: + self.applicationLayer.data.append(data) + self.udt_send(seq_num) + self.expected_seq_num += 1 + else: + self.udt_send(self.expected_seq_num - 1) + + def udt_send(self, ack_num): + if random.random() > 0.2: + self.networkLayer.socket.send(str(ack_num).encode()) + + def extract(self, message:str): + parts = message.split(" ") + seq_num = int(parts[0]) + data = parts[1] + return seq_num, data + +if __name__ == "__main__": + networkLayer = NetworkLayer() + applicationLayer = ApplicationLayer() + receiver = Receiver(networkLayer, applicationLayer) + while True: + message = networkLayer.udt_rcv() + if message: + seq_num, data = receiver.extract(message) + receiver.deliver_data(data, seq_num) + + diff --git a/Labs/Lab3/src/Sender.py b/Labs/Lab3/src/Sender.py new file mode 100644 index 0000000..7c79a65 --- /dev/null +++ b/Labs/Lab3/src/Sender.py @@ -0,0 +1,115 @@ +import time +import socket +import random + +class Package: + def __init__(self, data:str, seq_num:int) -> None: + self.data = data + self.seq_num = seq_num + + +class ApplicationLayer: + def __init__(self, data_len:int=5000) -> None: + self.data_len = data_len + self.data_to_send = [str(i) + str(i) + str(i) for i in range(data_len)] + self.data_index = 0 + + def get_data(self, query_length) -> list: + data = [(i, self.data_to_send[(self.data_index + i) % self.data_len]) for i in range(query_length)] + self.data_index = (self.data_index + query_length) % self.data_len + return data + + +class NetworkLayer: + def __init__(self, host="0.0.0.0", port=31415) -> None: + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.bind((host, port)) + self.socket.listen(1) + self.client_socket, address = self.socket.accept() + + def udt_send(self, data:str): + self.client_socket.send(data.encode()) + + def udt_rcv(self) -> int: + request = self.client_socket.recv(1024).decode("utf-8") + return request + +class Sender: + def __init__(self, window_size:int, timeout_ms:50, networkLayer:NetworkLayer) -> None: + self.window_size = window_size + 1 + self.window:list[Package] = [None] * self.window_size + self.base_num = 0 + self.next_seq_num = 0 + self.timeout_ms = timeout_ms + self.networkLayer = networkLayer + self.timer = None + + def rdt_send(self, data:str, seq_num:int) -> bool: + if ((self.next_seq_num + 1) % self.window_size != self.base_num): + self.window[self.next_seq_num] = Package(data, seq_num) + self.udt_send(self.window[self.next_seq_num].data, seq_num) + if (self.next_seq_num == self.base_num): + self.timer = time.time() + self.next_seq_num = (self.next_seq_num + 1) % self.window_size + return True + else: + return False + + def rdt_rcv(self, ack_index:int): + window_index = (ack_index - self.window[self.base_num].seq_num + self.window_size) % self.window_size + self.base_num = (self.base_num + window_index + 1) % self.window_size + if self.base_num == self.next_seq_num: + self.timer = None + + def udt_send(self, data:str, index:int): + if random.random() > 0.2: + index_data = str(index) + ' ' + data + self.networkLayer.udt_send(index_data) + + def is_timeout(self) -> bool: + if self.timer is None: + return False + return time.time() - self.timer >= 0.001 * self.timeout_ms + + def gbn(self): + window_index = self.base_num + while window_index != self.next_seq_num: + self.udt_send(self.window[window_index].data, self.window[window_index].seq_num) + window_index = (window_index + 1) % self.window_size + + def get_ack_num(self, ack_str:str): + ack_index = int(ack_str) + return ack_index + + +if __name__ == "__main__": + networkLayer = NetworkLayer(host="0.0.0.0", port=31415) + applicationLayer = ApplicationLayer() + sender = Sender( + window_size=50, + timeout_ms=50, + networkLayer=networkLayer, + ) + while True: + instruct = input() + + if instruct == "s": + pkg_list = applicationLayer.get_data(500) + index = 0 + while index != 100: + status = sender.rdt_send(pkg_list[index], index) + if status: + index += 1 + + ack_str = networkLayer.udt_rcv() + if ack_str: + ack_num = sender.get_ack_num(ack_str) + sender.rdt_rcv(ack_num) + + if sender.is_timeout(): + sender.gbn() + + if instruct == "q": + networkLayer.client_socket.close() + networkLayer.socket.close() + exit()