From eab9b922b599bf3b658ac22162ba14bf918d3875 Mon Sep 17 00:00:00 2001
From: typingbugs <jingfan.ke@qq.com>
Date: Wed, 3 Apr 2024 03:59:59 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E9=80=9A=E5=A4=A7=E9=83=A8=E5=88=86la?=
 =?UTF-8?q?b3=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 | 34 ++++++++++++++++---------
 Labs/Lab3/src/Sender.py   | 52 +++++++++++++++++++++++++++++----------
 2 files changed, 61 insertions(+), 25 deletions(-)
 mode change 100644 => 100755 Labs/Lab3/src/Receiver.py

diff --git a/Labs/Lab3/src/Receiver.py b/Labs/Lab3/src/Receiver.py
old mode 100644
new mode 100755
index 2f0d965..dabe71f
--- a/Labs/Lab3/src/Receiver.py
+++ b/Labs/Lab3/src/Receiver.py
@@ -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)
 
 
diff --git a/Labs/Lab3/src/Sender.py b/Labs/Lab3/src/Sender.py
index 7c79a65..d11af25 100644
--- a/Labs/Lab3/src/Sender.py
+++ b/Labs/Lab3/src/Sender.py
@@ -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()