74747Alice 5 dni temu
commit
9efa6e217b
4 zmienionych plików z 174 dodań i 0 usunięć
  1. 15 0
      README.md
  2. 41 0
      lorem_ipsum.txt
  3. 56 0
      udpclient.py
  4. 62 0
      udpserver.py

+ 15 - 0
README.md

@@ -0,0 +1,15 @@
+# 【计算机网络】实验 5:Socket 程序开发
+
+[项目地址](https://git.sdsz.icu/74747Alice/cn-socket)
+
+## 执行方法
+
+确保 `udpserver.py`、`udpclient.py`、待传输文件在同一目录,进入该目录。
+
+```bash
+python3 udpserver.py
+```
+
+```bash
+python3 udpclient.py 0.0.0.0:7474 lorem_ipsum.txt
+```

+ 41 - 0
lorem_ipsum.txt

@@ -0,0 +1,41 @@
+Hello, World!
+
+Individuals must have the ability to shape the internet and their own experiences on it.
+
+互联网用户必须能够依照个人意愿塑造互联网及其使用体验。
+
+個人は、インターネットと自らのインターネット上におけるエクスペリエンスを形成することが可能でなければなりません。
+
+Chacun doit pouvoir modeler Internet et l’usage qu’il en fait.
+
+يجب أن يتمتع الأفراد بالقدرة على تشكيل الإنترنت وتجاربهم الخاصة عليه.
+
+Los usuarios deben tener la posibilidad de definir la web y su propia experiencia en la red.
+
+As pessoas devem ter capacidade de moldar a internet e suas próprias experiências nela.
+
+Люди должны иметь возможность формировать Интернет и свое пребывание в нём.
+
+Menschen müssen das Internet und ihr eigenes Erlebnis darin gestalten können.
+
+Ogni persona deve avere la possibilità di contribuire allo sviluppo di Internet ed essere l’artefice della propria esperienza online.
+
+اشخاص باید بتوانند به اینترنت و تجربه خودشان از آن شکل بدهند.
+
+افراد میں انٹرنیٹ اور اس پر اپنے تجربات کی تشکیل کرنے کی صلاحیت ہونی چاہئے۔
+
+Люди повинні мати можливість формувати інтернет і своє перебування в ньому.
+
+74
+
+ⵉⵎⴷⴰⵏⴻⵏ ⴰⴽⴽⴻⵏ ⵎⴰ ⵍⵍⴰⵏ ⵜⵙⵍⴰⵍⴻⵏ-ⴷ ⴷ ⵉⵍⴻⵍⵍⵉⵢⴻⵏ ⴳⴷⴰⵏ ⴷⴻⴳ ⵍⵃⴻⵕⵎⴰ ⴷ ⵢⵉⵣⴻⵔⴼⴰⵏ, ⵖⵓⵔ-ⵙⴻⵏ ⵍⴻⵄⵇⴻⵍ ⴷ ⵜⴻⴼⵔⵉⵜ, ⵢⴻⵙⵙⴻⴼⴽ ⴰⴷ ⵜⵉⵍⵉ ⵜⴻⴳⵎⴰⵜ ⴳⴰⵔ-ⴰⵙⴻⵏ.
+
+የሰው፡ልጅ፡ሁሉ፡ሲወለድ፡ነጻና፡በክብርና፡በመብትም፡እኩልነት፡ያለው፡ነው።፡የተፈጥሮ፡ማስተዋልና፡ሕሊና፡ስላለው፡አንዱ፡ሌላውን፡በወንድማማችነት፡መንፈስ፡መመልከት፡ይገባዋል።
+
+يُولَدُ جَمِيعُ النَّاسِ أحْرَاراً مُتَسَاوِينَ فِي الْكَرَامَةِ وَالحُقُوقِ. وَقَدْ وُهِبُوا عَقْلاً وَ ضَمِيراً وَ عَلَيهِمْ أنْ يُعَامِلَ بَعْضُهُمْ بَعْضاً بِرُوحِ اَلإخَاء.
+
+כֹּל בְּנֵי הָאָדָם נוֹלְדוּ בְּנֵי חוֹרִין וְשָׁוִים בְּעֶרְכָּם וּבִזְכֻיּוֹתֵיהֶם. כֻּלָּם חוֹנְנוּ בַּתְּבוּנָה וּבְמַצְפּוּן, לְפִיכָךְ חוֹבָה עֲלֵיהֶם לִנְהֹוג אִישׁ בְּרֵעֵהוּ בְּרוּחַ שֶׁל אַחֲוָה.
+
+ܟܠ ܒܪܢܫܐ ܒܪܝܠܗ ܚܐܪܐ ܘܒܪܒܪ ܓܘ ܐܝܩܪܐ ܘܙܕܩܐ. ܘܦܝܫܝܠܗ ܝܗܒܐ ܗܘܢܐ ܘܐܢܝܬ. ܒܘܕ ܕܐܗܐ ܓܫܩܬܝ ܥܠ ܐܚܪܢܐ ܓܪܓ ܗܘܝܐ ܒܚܕ ܪܘܚܐ ܕܐܚܢܘܬܐ.
+
+人人生而自由,在尊严和权利上一律平等。他们赋有理性和良心,并应以兄弟关系的精神相对待。

+ 56 - 0
udpclient.py

@@ -0,0 +1,56 @@
+import socket
+import sys
+import os
+import time
+
+def start_client(ip, port, path):
+    if not os.path.exists(path): return
+    
+    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    addr = (ip, port)
+    (filename, filesize) = os.path.basename(path), os.path.getsize(path)
+
+    try:
+        print(f"\033[46m[客户端]\033[0m {ip}:{port},建立连接")
+        while True:
+            try:
+                client_socket.sendto(b"SYN", addr)
+                if client_socket.recv(1024) == b"SYN-ACK": break
+            except socket.timeout: continue
+
+        print(f"\033[46m[客户端]\033[0m 发送元数据:{filename}({filesize} 字节)")
+        while True:
+            try:
+                client_socket.sendto(f"META|{filename}|{filesize}".encode(), addr)
+                if client_socket.recv(1024) == b"META-ACK": break
+            except socket.timeout: continue
+
+        print("\033[46m[客户端]\033[0m 传输数据……")
+        with open(path, 'rb') as f:
+            while True:
+                chunk = f.read(1400)
+                if not chunk: break
+                client_socket.sendto(chunk, addr)
+                time.sleep(0.001) # 简单的流控制
+
+        print("\033[46m[客户端]\033[0m 释放连接")
+        for _ in range(3):
+            try:
+                client_socket.sendto(b"FIN", addr)
+                if client_socket.recv(1024) == b"FIN-ACK": break
+            except socket.timeout: continue
+        print("\033[46m[客户端]\033[0m 连接关闭")
+
+    except KeyboardInterrupt: pass
+    finally: client_socket.close()
+
+if __name__ == "__main__":
+    if len(sys.argv) < 3:
+        print("【用法】python3 file_sender.py <IP>:<端口> <文件路径>")
+        sys.exit(1)
+
+    try:
+        (ip, port) = sys.argv[1].split(':')
+        start_client(ip, int(port), sys.argv[2])
+    except ValueError:
+        print("【错误】地址格式应为 IP:端口")

+ 62 - 0
udpserver.py

@@ -0,0 +1,62 @@
+import socket
+import sys
+import os
+
+def start_server(ip, port):
+    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    addr = (ip, port)
+    server_socket.bind(addr)
+    print(f"\033[42m[服务端]\033[0m {ip}:{port},等待连接……")
+
+    while True:
+        # 建立连接 (模拟握手)
+        (data, client_addr) = server_socket.recvfrom(1024)
+        (client_ip, client_port) = client_addr
+        if data.decode('utf-8', errors='ignore') == "SYN":
+            print(f"\033[42m[服务端]\033[0m 来自客户端 {client_ip}:{client_port} 的连接请求")
+            server_socket.sendto("SYN-ACK".encode('utf-8'), client_addr)
+        else:
+            continue
+
+        # 接收元数据 META、文件名、大小
+        data, client_addr = server_socket.recvfrom(2048)
+        try:
+            _, filename, filesize = data.decode('utf-8').split('|')
+            filesize = int(filesize)
+            save_filename = f"{os.path.basename(filename)}" #######
+            print(f"\033[42m[服务端]\033[0m 接收数据:{filename}({filesize} 字节)……")
+            server_socket.sendto("META-ACK".encode('utf-8'), client_addr)
+        except:
+            continue
+
+        # 传输数据
+        received = 0
+        with open(save_filename, 'wb') as f:
+            while received < filesize:
+                chunk, _ = server_socket.recvfrom(2048)
+                if chunk == b"FIN": break
+                f.write(chunk)
+                received += len(chunk)
+        print(f"\033[42m[服务端]\033[0m 保存文件:{save_filename}")
+
+        # 释放连接(模拟挥手)
+        data, _ = server_socket.recvfrom(1024)
+        if data.decode('utf-8', errors='ignore') == "FIN":
+            print("\033[42m[服务端]\033[0m 断开连接")
+            server_socket.sendto("FIN-ACK".encode('utf-8'), client_addr)
+            print(f"\033[42m[服务端]\033[0m {ip}:{port},等待连接……")
+
+        # break # 可加可不加
+
+if __name__ == "__main__":
+    (ip, port) = "0.0.0.0", 7474
+
+    if len(sys.argv) > 1:
+        try:
+            (ip, port) = sys.argv[1].split(':')
+            port = int(port)
+        except ValueError:
+            print("【错误】地址格式应为 IP:端口")
+            sys.exit(1)
+
+    start_server(ip, port)