lab3完成代码部分
This commit is contained in:
parent
eab9b922b5
commit
2de63a3dc8
@ -1,18 +1,22 @@
|
|||||||
import socket
|
import socket
|
||||||
import random
|
import random
|
||||||
import re
|
import time
|
||||||
|
|
||||||
class NetworkLayer:
|
class NetworkLayer:
|
||||||
def __init__(self, host="172.29.68.245", port=23666) -> None:
|
def __init__(self, host:str, port:int) -> None:
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.socket.connect((host, port))
|
self.socket.connect((host, port))
|
||||||
|
print("下层的不可靠传输连接成功,等待发送方传输。")
|
||||||
|
|
||||||
def udt_send(self, data:str):
|
def udt_send(self, data:str):
|
||||||
self.socket.send(data.encode())
|
self.socket.send(data.encode())
|
||||||
|
|
||||||
def udt_rcv(self) -> str:
|
def udt_rcv(self) -> str:
|
||||||
message = self.socket.recv(1024).decode("utf-8")
|
message = self.socket.recv(12).decode("utf-8")
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.socket.close()
|
||||||
|
|
||||||
|
|
||||||
class ApplicationLayer:
|
class ApplicationLayer:
|
||||||
@ -22,13 +26,13 @@ class ApplicationLayer:
|
|||||||
|
|
||||||
class Receiver:
|
class Receiver:
|
||||||
def __init__(self, networkLayer:NetworkLayer, applicationLayer:ApplicationLayer):
|
def __init__(self, networkLayer:NetworkLayer, applicationLayer:ApplicationLayer):
|
||||||
self.expected_seq_num = 0
|
self.expected_seq_num = 1
|
||||||
self.networkLayer = networkLayer
|
self.networkLayer = networkLayer
|
||||||
self.applicationLayer = applicationLayer
|
self.applicationLayer = applicationLayer
|
||||||
|
|
||||||
def deliver_data(self, data, seq_num):
|
def deliver_data(self, data, seq_num):
|
||||||
if seq_num == self.expected_seq_num:
|
if seq_num == self.expected_seq_num:
|
||||||
print(f'成功收到seq_num={seq_num}, data={data}的包。')
|
print(f'成功收到seq_num={seq_num}, data=\"{data}\"的包。')
|
||||||
self.applicationLayer.data.append(data)
|
self.applicationLayer.data.append(data)
|
||||||
self.udt_send(seq_num)
|
self.udt_send(seq_num)
|
||||||
self.expected_seq_num += 1
|
self.expected_seq_num += 1
|
||||||
@ -39,30 +43,28 @@ class Receiver:
|
|||||||
def udt_send(self, ack_num):
|
def udt_send(self, ack_num):
|
||||||
print(f"发送ACK={ack_num}", end="")
|
print(f"发送ACK={ack_num}", end="")
|
||||||
if random.random() > 0.25:
|
if random.random() > 0.25:
|
||||||
self.networkLayer.socket.send((str(ack_num) + "\n").encode())
|
self.networkLayer.socket.send("{:0>4d}".format(ack_num).encode())
|
||||||
else:
|
else:
|
||||||
print(",此包丢失。", end="")
|
print(",此包丢失。", end="")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
def extract(self, message:str):
|
def extract(self, message:str):
|
||||||
try:
|
seq_num = int(message[:3])
|
||||||
parts = message.split(" ")
|
data = message[4:]
|
||||||
seq_num = int(parts[0])
|
return seq_num, data
|
||||||
data = parts[1]
|
|
||||||
return seq_num, data
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
networkLayer = NetworkLayer()
|
max_seq_num = 20
|
||||||
|
networkLayer = NetworkLayer(host="172.29.68.245", port=23666)
|
||||||
applicationLayer = ApplicationLayer()
|
applicationLayer = ApplicationLayer()
|
||||||
receiver = Receiver(networkLayer, applicationLayer)
|
receiver = Receiver(networkLayer, applicationLayer)
|
||||||
while True:
|
while True:
|
||||||
message = networkLayer.udt_rcv()
|
message = networkLayer.udt_rcv()
|
||||||
if message:
|
if message:
|
||||||
seq_num, data = receiver.extract(message)
|
seq_num, data = receiver.extract(message)
|
||||||
if data:
|
receiver.deliver_data(data, seq_num)
|
||||||
receiver.deliver_data(data, seq_num)
|
if receiver.expected_seq_num == max_seq_num:
|
||||||
|
break
|
||||||
|
print("序列传输完成。")
|
||||||
|
networkLayer.close()
|
||||||
|
|
||||||
|
@ -1,32 +1,27 @@
|
|||||||
import time
|
import time
|
||||||
import socket
|
import socket
|
||||||
import random
|
import random
|
||||||
import re
|
|
||||||
|
|
||||||
class Package:
|
class Package:
|
||||||
def __init__(self, data:str, seq_num:int) -> None:
|
def __init__(self, data:str, seq_num:int) -> None:
|
||||||
self.data = data
|
self.data = data
|
||||||
self.seq_num = seq_num
|
self.seq_num = seq_num
|
||||||
|
self.send_time = None
|
||||||
|
|
||||||
|
|
||||||
class ApplicationLayer:
|
class ApplicationLayer:
|
||||||
def __init__(self, data_len:int=5000) -> None:
|
def __init__(self, data_len:int=5000) -> None:
|
||||||
self.data_len = data_len
|
self.data_len = data_len
|
||||||
self.data_to_send = [str(i) + str(i) + str(i) for i in range(data_len)]
|
self.data_to_send = ["data{:0>4d}".format(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:
|
class NetworkLayer:
|
||||||
def __init__(self, host="0.0.0.0", port=23666) -> None:
|
def __init__(self, host:str, port:int) -> None:
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.socket.bind((host, port))
|
self.socket.bind((host, port))
|
||||||
self.socket.listen(1)
|
self.socket.listen(1)
|
||||||
|
print("等待下层的不可靠传输连接。")
|
||||||
self.client_socket, address = self.socket.accept()
|
self.client_socket, address = self.socket.accept()
|
||||||
|
print("下层的不可靠传输连接成功。")
|
||||||
self.client_socket.setblocking(False)
|
self.client_socket.setblocking(False)
|
||||||
|
|
||||||
def udt_send(self, data:str):
|
def udt_send(self, data:str):
|
||||||
@ -34,42 +29,63 @@ class NetworkLayer:
|
|||||||
|
|
||||||
def udt_rcv(self):
|
def udt_rcv(self):
|
||||||
try:
|
try:
|
||||||
return self.client_socket.recv(1024).decode("utf-8")
|
return self.client_socket.recv(4).decode("utf-8")
|
||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.client_socket.close()
|
||||||
|
self.socket.close()
|
||||||
|
|
||||||
class Sender:
|
class Sender:
|
||||||
def __init__(self, window_size:int, timeout_ms:1200, networkLayer:NetworkLayer) -> None:
|
def __init__(
|
||||||
self.window_size = window_size + 1
|
self,
|
||||||
self.window:list[Package] = [None] * self.window_size
|
window_size:int,
|
||||||
self.base_num = 0
|
max_seq_num:int,
|
||||||
self.next_seq_num = 0
|
timeout_ms:2000,
|
||||||
|
networkLayer:NetworkLayer,
|
||||||
|
) -> None:
|
||||||
|
self.window_size = window_size
|
||||||
|
self.max_seq_num = max_seq_num
|
||||||
|
self.package_list:list[Package] = [None] * (self.max_seq_num + 1)
|
||||||
|
self.base_num = 1
|
||||||
|
self.next_seq_num = 1
|
||||||
self.timeout_ms = timeout_ms
|
self.timeout_ms = timeout_ms
|
||||||
self.networkLayer = networkLayer
|
self.networkLayer = networkLayer
|
||||||
self.timer = None
|
self.timer = False
|
||||||
|
|
||||||
def rdt_send(self, data:str, seq_num:int) -> bool:
|
def rdt_send(self, data:str) -> bool:
|
||||||
if ((self.next_seq_num + 1) % self.window_size != self.base_num):
|
if self.next_seq_num > max_seq_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
|
return False
|
||||||
|
if self.next_seq_num >= self.base_num + self.window_size:
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.package_list[self.next_seq_num] = Package(data, self.next_seq_num)
|
||||||
|
self.udt_send(
|
||||||
|
self.package_list[self.next_seq_num].data,
|
||||||
|
self.package_list[self.next_seq_num].seq_num
|
||||||
|
)
|
||||||
|
self.package_list[self.next_seq_num].send_time = time.time()
|
||||||
|
if self.base_num == self.next_seq_num:
|
||||||
|
self.timer = True
|
||||||
|
self.next_seq_num += 1
|
||||||
|
return True
|
||||||
|
|
||||||
def rdt_rcv(self, ack_index:int):
|
def rdt_rcv(self, ack_index:int):
|
||||||
print(f"收到ACK={ack_index},", end="")
|
print(f"收到ACK={ack_index},", end="")
|
||||||
window_index = (ack_index - self.window[self.base_num].seq_num + self.window_size) % self.window_size
|
if (ack_index < self.base_num):
|
||||||
self.base_num = (self.base_num + window_index + 1) % self.window_size
|
print(f"(ACK={ack_index}) < (base={self.base_num}),ACK失效丢弃。")
|
||||||
print(f"将base_num设置为{self.base_num}。")
|
return
|
||||||
|
self.base_num = ack_index + 1
|
||||||
if self.base_num == self.next_seq_num:
|
if self.base_num == self.next_seq_num:
|
||||||
self.timer = None
|
print(f"将base_num设置为下一个序列编号。")
|
||||||
|
self.timer = False
|
||||||
|
else:
|
||||||
|
print(f"将base_num设置为{self.package_list[self.base_num].seq_num}。")
|
||||||
|
|
||||||
def udt_send(self, data:str, index:int):
|
def udt_send(self, data:str, index:int):
|
||||||
index_data = str(index) + ' ' + data + "\n"
|
index_data = '{:0>3d} '.format(index) + data
|
||||||
print(f"发送data={index_data[:-1]}", end="")
|
print(f"发送data=\"{index_data}\"", end="")
|
||||||
if random.random() > 0.25:
|
if random.random() > 0.25:
|
||||||
self.networkLayer.udt_send(index_data)
|
self.networkLayer.udt_send(index_data)
|
||||||
else:
|
else:
|
||||||
@ -77,65 +93,73 @@ class Sender:
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
def is_timeout(self) -> bool:
|
def is_timeout(self) -> bool:
|
||||||
if self.timer is None:
|
if self.timer is False:
|
||||||
return False
|
return False
|
||||||
return time.time() - self.timer >= 0.001 * self.timeout_ms
|
return time.time() - self.package_list[self.base_num].send_time >= 0.001 * self.timeout_ms
|
||||||
|
|
||||||
def gbn(self):
|
def gbn(self):
|
||||||
window_index = self.base_num
|
seq_index = self.base_num
|
||||||
while window_index != self.next_seq_num:
|
while seq_index < self.next_seq_num:
|
||||||
self.udt_send(self.window[window_index].data, self.window[window_index].seq_num)
|
self.udt_send(
|
||||||
window_index = (window_index + 1) % self.window_size
|
self.package_list[seq_index].data,
|
||||||
|
self.package_list[seq_index].seq_num
|
||||||
|
)
|
||||||
|
self.package_list[seq_index].send_time = time.time()
|
||||||
|
seq_index += 1
|
||||||
|
|
||||||
|
def show_gbn(self) -> list[int]:
|
||||||
|
show = []
|
||||||
|
seq_index = self.base_num
|
||||||
|
while seq_index < self.next_seq_num:
|
||||||
|
show.append(self.package_list[seq_index].seq_num)
|
||||||
|
seq_index += 1
|
||||||
|
return show
|
||||||
|
|
||||||
def get_ack_num(self, ack_str:str) -> int:
|
def get_ack_num(self, ack_str:str) -> int:
|
||||||
try:
|
return int(ack_str)
|
||||||
return int(ack_str.strip())
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
networkLayer = NetworkLayer()
|
max_seq_num = 20
|
||||||
applicationLayer = ApplicationLayer()
|
networkLayer = NetworkLayer(host="0.0.0.0", port=23666)
|
||||||
|
applicationLayer = ApplicationLayer(max_seq_num)
|
||||||
sender = Sender(
|
sender = Sender(
|
||||||
window_size=50,
|
window_size=4,
|
||||||
timeout_ms=50,
|
max_seq_num=max_seq_num,
|
||||||
|
timeout_ms=2000,
|
||||||
networkLayer=networkLayer,
|
networkLayer=networkLayer,
|
||||||
)
|
)
|
||||||
while True:
|
instruct = input("按回车键开始传输:")
|
||||||
instruct = input()
|
|
||||||
|
pkg_list = applicationLayer.data_to_send
|
||||||
|
index = 1
|
||||||
|
while index <= max_seq_num:
|
||||||
|
time.sleep(1)
|
||||||
|
data = pkg_list[index - 1]
|
||||||
|
status = sender.rdt_send(data)
|
||||||
|
if status:
|
||||||
|
index += 1
|
||||||
|
|
||||||
if instruct == "s":
|
ack_str = networkLayer.udt_rcv()
|
||||||
pkg_list = applicationLayer.get_data(500)
|
if ack_str is not None:
|
||||||
index = 0
|
ack_num = sender.get_ack_num(ack_str)
|
||||||
while index != 100:
|
sender.rdt_rcv(ack_num)
|
||||||
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 sender.is_timeout():
|
||||||
if ack_str:
|
print(f"超时。重传{sender.show_gbn()}")
|
||||||
ack_num = sender.get_ack_num(ack_str)
|
sender.gbn()
|
||||||
if ack_num is not None:
|
|
||||||
sender.rdt_rcv(ack_num)
|
|
||||||
|
|
||||||
if sender.is_timeout():
|
while sender.base_num < sender.next_seq_num:
|
||||||
sender.gbn()
|
time.sleep(1)
|
||||||
|
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)
|
||||||
|
|
||||||
while sender.base_num != sender.next_seq_num:
|
if sender.is_timeout():
|
||||||
ack_str = networkLayer.udt_rcv()
|
print(f"超时。重传{sender.show_gbn()}")
|
||||||
if ack_str:
|
sender.gbn()
|
||||||
ack_num = sender.get_ack_num(ack_str)
|
|
||||||
if ack_num is not None:
|
print("序列传输完成。")
|
||||||
sender.rdt_rcv(ack_num)
|
networkLayer.close()
|
||||||
|
|
||||||
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