初步完成lab3代码
This commit is contained in:
parent
341d753c76
commit
4b06b2f9b3
58
Labs/Lab3/src/Receiver.py
Normal file
58
Labs/Lab3/src/Receiver.py
Normal file
@ -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)
|
||||
|
||||
|
115
Labs/Lab3/src/Sender.py
Normal file
115
Labs/Lab3/src/Sender.py
Normal file
@ -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()
|
Loading…
x
Reference in New Issue
Block a user