调通大部分lab3代码

This commit is contained in:
typingbugs 2024-04-03 03:59:59 +08:00
parent 4b06b2f9b3
commit eab9b922b5
2 changed files with 61 additions and 25 deletions

34
Labs/Lab3/src/Receiver.py Normal file → Executable file
View File

@ -1,8 +1,9 @@
import socket
import random
import re
class NetworkLayer:
def __init__(self, host="0.0.0.0", port=31415) -> None:
def __init__(self, host="172.29.68.245", port=23666) -> None:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((host, port))
@ -10,11 +11,9 @@ class NetworkLayer:
self.socket.send(data.encode())
def udt_rcv(self) -> str:
while True:
message = self.socket.recv(1024).decode("utf-8")
return message
message = self.socket.recv(1024).decode("utf-8")
return message
class ApplicationLayer:
def __init__(self) -> None:
@ -29,21 +28,31 @@ class Receiver:
def deliver_data(self, data, seq_num):
if seq_num == self.expected_seq_num:
print(f'成功收到seq_num={seq_num}, data={data}的包。')
self.applicationLayer.data.append(data)
self.udt_send(seq_num)
self.expected_seq_num += 1
else:
print(f'收到seq_num={seq_num}, 与预期seq_num={self.expected_seq_num}不符。')
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())
print(f"发送ACK={ack_num}", end="")
if random.random() > 0.25:
self.networkLayer.socket.send((str(ack_num) + "\n").encode())
else:
print(",此包丢失。", end="")
print()
def extract(self, message:str):
parts = message.split(" ")
seq_num = int(parts[0])
data = parts[1]
return seq_num, data
try:
parts = message.split(" ")
seq_num = int(parts[0])
data = parts[1]
return seq_num, data
except Exception as e:
print(e)
return None, None
if __name__ == "__main__":
networkLayer = NetworkLayer()
@ -53,6 +62,7 @@ if __name__ == "__main__":
message = networkLayer.udt_rcv()
if message:
seq_num, data = receiver.extract(message)
receiver.deliver_data(data, seq_num)
if data:
receiver.deliver_data(data, seq_num)

View File

@ -1,6 +1,7 @@
import time
import socket
import random
import re
class Package:
def __init__(self, data:str, seq_num:int) -> None:
@ -21,21 +22,24 @@ class ApplicationLayer:
class NetworkLayer:
def __init__(self, host="0.0.0.0", port=31415) -> None:
def __init__(self, host="0.0.0.0", port=23666) -> 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()
self.client_socket.setblocking(False)
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
def udt_rcv(self):
try:
return self.client_socket.recv(1024).decode("utf-8")
except BlockingIOError:
return None
class Sender:
def __init__(self, window_size:int, timeout_ms:50, networkLayer:NetworkLayer) -> None:
def __init__(self, window_size:int, timeout_ms:1200, networkLayer:NetworkLayer) -> None:
self.window_size = window_size + 1
self.window:list[Package] = [None] * self.window_size
self.base_num = 0
@ -56,15 +60,21 @@ class Sender:
return False
def rdt_rcv(self, ack_index:int):
print(f"收到ACK={ack_index}", end="")
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
print(f"将base_num设置为{self.base_num}")
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
index_data = str(index) + ' ' + data + "\n"
print(f"发送data={index_data[:-1]}", end="")
if random.random() > 0.25:
self.networkLayer.udt_send(index_data)
else:
print(",此包丢失。", end="")
print()
def is_timeout(self) -> bool:
if self.timer is None:
@ -77,13 +87,16 @@ class Sender:
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
def get_ack_num(self, ack_str:str) -> int:
try:
return int(ack_str.strip())
except Exception as e:
print(e)
return None
if __name__ == "__main__":
networkLayer = NetworkLayer(host="0.0.0.0", port=31415)
networkLayer = NetworkLayer()
applicationLayer = ApplicationLayer()
sender = Sender(
window_size=50,
@ -97,14 +110,27 @@ if __name__ == "__main__":
pkg_list = applicationLayer.get_data(500)
index = 0
while index != 100:
status = sender.rdt_send(pkg_list[index], index)
time.sleep(0.5)
seq_num, data = pkg_list[index]
status = sender.rdt_send(data, seq_num)
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 ack_num is not None:
sender.rdt_rcv(ack_num)
if sender.is_timeout():
sender.gbn()
while sender.base_num != sender.next_seq_num:
ack_str = networkLayer.udt_rcv()
if ack_str:
ack_num = sender.get_ack_num(ack_str)
if ack_num is not None:
sender.rdt_rcv(ack_num)
if sender.is_timeout():
sender.gbn()