實驗四 增強型可靠文件傳輸系統

一、實驗目的和任務

  1. 掌握基于隊列的多文件傳輸機制
  2. 理解斷點續傳的實現原理
  3. 學習文件傳輸完整性保障方法

二、實驗內容

基礎功能驗證

  1. 單文件傳輸功能測試
  2. 服務器狀態監控測試
  3. 傳輸日志記錄驗證

新增功能實現

  1. 多文件隊列傳輸功能
  2. 斷點續傳支持

三、實驗步驟

4.1 客戶端功能擴展

參考代碼:

關鍵代碼修改點:

文件隊列管理:
# 新增隊列和狀態變量
self.file_queue = queue.Queue()
self.is_transferring = False
# 修改后的文件選擇方法
def select_file(self):filepaths = filedialog.askopenfilenames()if filepaths:for filepath in filepaths:self.file_queue.put(filepath)self.log.insert(END, f"已添加: {os.path.basename(filepath)}\n")if not self.is_transferring:threading.Thread(target=self.process_queue).start()
新增隊列處理線程:
def process_queue(self):self.is_transferring = Truewhile not self.file_queue.empty():filepath = self.file_queue.get()self.upload_file(filepath)
self.is_transferring = False
斷點續傳功能:
上傳文件方法修改def upload_file(self, filepath):try:client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(('localhost', 12345))# 發送文件元數據filename = os.path.basename(filepath)filesize = os.path.getsize(filepath)client.send(f"{filename} |{filesize}".encode())# 等待服務器確認ack = client.recv(1024).decode()if ack.startswith('RESUME'):recieved?= int(ack.split('|')[1])mode?= 'rb+' ?#從斷點處繼續讀else:recieved?= 0mode?= 'rb'# 分塊傳輸文件with open(filepath, mode) as f:f.seek(recieved)while recieved?<filesize:chunk = f.read(1024)if chunk:client.send(chunk)recieved?+= len(chunk)self.log.insert(END, f"{filename} 傳輸成功\n")except Exception as e:self.log.insert(END, f"錯誤: {e}\n")finally:client.close()

完整python腳本如下:

import socket
import os
import threading
import queue
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
class FileTransferClient:def __init__(self, root):self.root = rootself.root.title("文件傳輸客戶端")# 文件隊列和狀態self.file_queue = queue.Queue()self.is_transferring = False# 創建界面組件self.create_widgets()def create_widgets(self):# 文件選擇按鈕self.select_btn = Button(self.root, text="選擇文件", command=self.select_file)self.select_btn.pack(pady=10)# 傳輸日志self.log = Text(self.root, height=15, width=60)self.log.pack(pady=10)def select_file(self):filepaths = filedialog.askopenfilenames()if filepaths:for filepath in filepaths:self.file_queue.put(filepath)self.log.insert(END, f"已添加: {os.path.basename(filepath)}\n")if not self.is_transferring:threading.Thread(target=self.process_queue).start()def process_queue(self):self.is_transferring = Truewhile not self.file_queue.empty():filepath = self.file_queue.get()self.upload_file(filepath)self.is_transferring = Falsedef upload_file(self, filepath):try:client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(('localhost', 12345))# 發送文件元數據filename = os.path.basename(filepath)filesize = os.path.getsize(filepath)client.send(f"{filename}|{filesize}".encode())# 等待服務器確認ack = client.recv(1024).decode()if ack.startswith('RESUME'):received = int(ack.split('|')[1])mode = 'rb+'else:received = 0mode = 'rb'# 分塊傳輸文件with open(filepath, mode) as f:f.seek(received)while received < filesize:data = f.read(1024)if not data:breakclient.send(data)received += len(data)self.log.insert(END, f"{filename} 傳輸成功\n")except Exception as e:self.log.insert(END, f"錯誤: {e}\n")finally:client.close()
if __name__ == "__main__":root = Tk()app = FileTransferClient(root)root.mainloop()

4.2 服務器功能擴展

參考代碼:

關鍵代碼修改點:

斷點續傳支持:
def handle_client(self, client_socket):# 檢查文件是否存在if os.path.exists(filename):received = os.path.getsize(filename)client_socket.send(f"RESUME|{received}".encode())mode = 'ab' ?# 追加模式else:client_socket.send(b"ACK")mode = 'wb'received = 0

完整python腳本如下:??


import socket
import os
import threading
from datetime import datetime
class FileTransferServer:def __init__(self, host='localhost', port=12345):self.host = hostself.port = portself.server_socket = Noneself.running = Falsedef start(self):self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.server_socket.bind((self.host, self.port))self.server_socket.listen(5)self.running = Trueprint(f"服務器啟動,監聽 {self.host}:{self.port}")while self.running:try:client_socket, addr = self.server_socket.accept()print(f"新連接來自: {addr}")# 為每個客戶端創建新線程client_thread = threading.Thread(target=self.handle_client,args=(client_socket,))client_thread.start()except Exception as e:print(f"服務器錯誤: {e}")breakdef stop(self):self.running = Falseif self.server_socket:self.server_socket.close()print("服務器已停止")def handle_client(self, client_socket):try:# 接收文件元數據metadata = client_socket.recv(1024).decode()filename, filesize = metadata.split('|')filesize = int(filesize)# 檢查文件是否存在if os.path.exists(filename):received = os.path.getsize(filename)client_socket.send(f"RESUME|{received}".encode())mode = 'ab'  # 追加模式else:client_socket.send(b"ACK")mode = 'wb'received = 0# 接收文件數據with open(filename, mode) as f:while received < filesize:data = client_socket.recv(1024)if not data:breakf.write(data)received += len(data)print(f"文件 {filename} 接收完成 ({received}/{filesize} bytes)")except Exception as e:print(f"處理客戶端時出錯: {e}")finally:client_socket.close()
if __name__ == "__main__":server = FileTransferServer()try:server.start()except KeyboardInterrupt:server.stop()

4.3 實驗驗證步驟

  1. 基礎傳輸測試:
  1. 啟動Server.py
  2. 運行Client.py
  3. 選擇單個文件傳輸
  4. 觀察服務器接收情況
  1. 多文件隊列測試:
  1. 啟動Server2.py
  2. 運行Client2.py
  3. 同時選擇多個文件(建議3-5個)
  4. 觀察隊列傳輸順序和日志記錄
  1. 斷點續傳測試:
  1. 傳輸大文件(>50MB)
  2. 在傳輸過程中強制關閉客戶端
  3. 重新啟動傳輸同一文件
  4. 驗證文件完整性(通過文件大小比對)

四、測試結果

五、思考題

1.MD5校驗是否能完全保證文件正確性?為什么?

????????MD5校驗不能完全保證文件的正確性。雖然MD5可以用來檢測文件完整性,因為它通過生成一個固定長度的哈希值來唯一標識文件內容,但如果兩個不同的文件生成了相同的MD5哈希值(這種情況稱為哈希碰撞),那么MD5校驗就無法區分這兩個文件了。此外,MD5已經被證明不夠安全,存在被惡意攻擊者故意構造碰撞的情況。因此,對于需要更高安全性的場景,通常推薦使用更安全的哈希算法,如SHA-256。

2.進度條更新為什么要用after()方法?

????????在GUI編程中,after()方法常用于非阻塞地執行某些任務,比如定時更新進度條。這是因為after()方法可以在指定的時間間隔后執行一個函數或方法調用,而不需要阻塞主線程。這樣可以保持用戶界面的響應性,防止因為長時間的計算或網絡操作導致界面卡頓。

3.如何實現服務端的多客戶端并發處理?

????????實現服務端的多客戶端并發處理通常可以采用多線程或多進程的方式。例如,在Python中可以使用socket庫結合threadingmultiprocessing庫來為每個客戶端創建一個獨立的線程或進程,從而實現并發。另一種方法是使用異步編程,如asyncio庫,通過事件循環管理多個客戶端的請求,這種方式在處理大量并發連接時效率更高。

4.傳輸過程中突然關閉窗口會導致什么問題?如何解決?

????????傳輸過程中突然關閉窗口可能會導致數據傳輸不完整,文件損壞,或者服務端和客戶端之間的連接異常中斷。為了解決這個問題,通常可以采用以下措施:

  • 實現數據包的確認機制,確保每個數據包都被正確接收。

  • 使用斷點續傳功能,使得在傳輸中斷后可以從上次中斷的位置繼續傳輸。

  • 設計良好的錯誤處理機制,能夠在檢測到連接中斷時嘗試恢復連接或通知用戶重新傳輸文件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78444.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78444.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78444.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網絡Tips20-003

1.E1載波的控制開銷占2/32*100%6.25%&#xff0c;E1載波的基本幀傳送時間是125uS。 2.計算機在一個指令周期的過程中&#xff0c;為從內存讀取指令操作碼&#xff0c;首先要將.程序計數器(PC)的內容送到地址總線上 3.3DES算法:密碼學中&#xff0c;3DES是三重數據加密算法通稱…

【MySQL】索引(重要)

目錄 一、索引本質&#xff1a; 索引的核心作用 索引的優缺點 二、預備知識&#xff1a; 硬件理解&#xff1a; 軟件理解&#xff1a; MySQL與磁盤交互基本單位&#xff1a; 三、索引的理解&#xff1a; 理解page&#xff1a; 單個page&#xff1a; 多個page&#x…

【深入淺出MySQL】之數據類型介紹

【深入淺出MySQL】之數據類型介紹 MySQL中常見的數據類型一覽為什么需要如此多的數據類型數值類型BIT&#xff08;M&#xff09;類型INT類型TINYINT類型BIGINT類型浮點數類型float類型DECIMAL(M,D)類型區別總結 字符串類型CHAR類型VARCHAR(M)類型 日期和時間類型enum和set類型 …

數字化時代下,軟件測試中的滲透測試是如何保障安全的?

在如今數字化與信息化的時代&#xff0c;軟件測試中存在滲透測試&#xff0c;其位置十分重要&#xff0c;它借助模擬惡意攻擊的方式&#xff0c;去發現軟件系統所存在的漏洞以及安全問題&#xff0c;這是保障軟件安全的關鍵環節&#xff0c;接下來我會對它的各個方面進行詳細介…

Pytorch - Developer Notes 1/2

文章目錄 自動混合精度示例典型的混合精度訓練處理未縮放梯度梯度裁剪 處理縮放梯度梯度累積梯度懲罰 處理多個模型、損失函數和優化器多 GPU 工作環境下的注意事項單進程中的DataParallel分布式數據并行&#xff1a;每個進程對應一個GPU每個進程使用多塊GPU的DistributedDataP…

RuntimeError: CUDA error: __global__ function call is not configured

表明在 CUDA 設備上調用的核函數 沒有正確配置線程塊和網格維度。 一般體現在&#xff1a; 直接調用 kernel 函數&#xff0c;而不是通過 launch 函數 指定 kernel 函數調用 解決方法&#xff08;示例&#xff09;&#xff1a; // kernel function __global__ void Idtest_k…

cloudfare+gmail 配置 smtp 郵箱

這里介紹有一個域名后&#xff0c;不需要服務器&#xff0c;就可以實現 cloudfare gmail 的 郵箱收發。 為什么還需要 gmail 的 smtp 功能&#xff0c;因為 cloudfare 默認只是對 email 進行轉發&#xff0c;就是只能收郵件而不能發送郵件&#xff0c;故使用 gmail 的功能來進…

如何在 CentOS 7 命令行連接 Wi-Fi?如何在 Linux 命令行連接 Wi-Fi?

如何在 CentOS 7 命令行連接 Wi-Fi&#xff1f;如何在 Linux 命令行連接 Wi-Fi&#xff1f; 摘要 本教程覆蓋如何在多種 Linux 發行版下通過命令行連接 Wi-Fi&#xff0c;包括&#xff1a; CentOS 7、Ubuntu、Debian、Arch Linux、Fedora、Alpine Linux、Kali Linux、OpenSU…

基于PHP的在線編程課程學習系統

有需要請加文章底部Q哦 可遠程調試 基于PHP在線編程課程學習系統 一 介紹 在線編程課程學習系統基于原生PHP開發&#xff0c;數據庫mysql&#xff0c;前端jquery.js。系統角色分為學生&#xff0c;教師和管理員。(附帶參考設計文檔) 技術棧&#xff1a;phpmysqljquery.jsphps…

PyTorch_張量形狀操作

搭建模型時&#xff0c;數據都是基于張量形式的表示&#xff0c;網絡層與層之間很多都是以不同的shape的方式進行表現和運算。 對張量形狀的操作&#xff0c;以便能夠更好處理網絡各層之間的數據連接。 reshape 函數的用法 reshape 函數可以再保證張量數據不變的前提下改變數…

大模型實踐:圖文解鎖Ollama在個人筆記本上部署llm

使用在線模型服務時&#xff0c;我們常常需要支付API調用費用&#xff0c;這對于個人開發者或小型組織來說可能是一筆不小的開支。那么&#xff0c;有沒有方法可以在本地免費使用這些強大的模型呢&#xff1f;答案是肯定的——Ollama就是這樣一個工具。 當然如果是比較大的組織…

Python基本語法(lambda表達式)

lambda表達式 lambda的一般形式是在關鍵字lambda后面跟一個或多個參數&#xff0c;之后再緊跟一個 冒號&#xff0c;接下來是一個表達式。lambda是一個表達式&#xff0c;而不是一個語句&#xff0c;它能夠出現 在Python語法不允許def出現的地方。作為表達式&#xff0c;lambd…

【MySQL數據庫】用戶管理

目錄 1&#xff0c;用戶信息 2&#xff0c;創建/刪除/修改用戶 3&#xff0c;數據庫的權限 MySQL數據庫安裝完之后&#xff0c;我們最開始時使用的都是 root 用戶&#xff0c;其它用戶通常無法進行操作。因此&#xff0c;MySQL數據庫需要對用戶進行管理。 1&#xff0c;用戶…

Python的ArcPy基于Excel表格對大量遙感影像批量重分類

本文介紹基于Python中的ArcPy模塊&#xff0c;以Excel表格內的信息&#xff0c;對遙感影像加以重分類的方法。 首先&#xff0c;明確一下本文的需求。現有按照文章ArcPy批量將柵格文件的屬性表導出為Excel表格的方法&#xff08;https://blog.csdn.net/zhebushibiaoshifu/artic…

LabVIEW 中VI Server導出 VI 配置

該 LabVIEW VI 展示了在 VI Server 中配置和執行 Exported VIs 的過程&#xff0c;實現對服務器端導出 VI 的遠程調用與操作。 ? 具體過程及模塊說明 前期配置&#xff1a;需確保在 LabVIEW 的 “Tools> Options > VI Server > Protocols” 路徑下&#xff0c;啟用 …

論文閱讀:2024 ACM SIGSAC Membership inference attacks against in-context learning

總目錄 大模型安全相關研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 Membership inference attacks against in-context learning https://arxiv.org/pdf/2409.01380 https://www.doubao.com/chat/4030440311895554 速覽 這篇論文主要研究了…

從 Python 基礎到 Django 實戰 —— 數據類型驅動的 Web 開發之旅

主題簡介&#xff1a; 本主題以 Python 基礎數據類型為核心&#xff0c;結合 Django 框架的開發流程&#xff0c;系統講解如何通過掌握數字、字符串、列表、元組、字典等基礎類型&#xff0c;快速構建功能完善的 Web 應用。通過理論與實踐結合&#xff0c;幫助學員從零基礎 Py…

軟考 系統架構設計師系列知識點之雜項集萃(53)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;52&#xff09; 第85題 在靜態測試中&#xff0c;主要是對程序代碼進行靜態分析。“數據初始化、賦值或引用過程中的異常”屬于靜態分析中的&#xff08;&#xff09;。 A. 控制流分析 B. 數據…

Raycaster光線投射

Raycaster光線投射 3D虛擬工廠在線體驗 描述 光線投射Raycaster&#xff0c;用于進行raycasting&#xff08;光線投射&#xff09;。 光線投射用于進行鼠標拾取&#xff08;在三維空間中計算出鼠標移過了什么物體&#xff09;。 構造器 Raycaster( origin : Vector3, dire…

初識Linux —— git三板斧

版本控制器git 為了我們方便管理不同版本的文件&#xff0c;就有了版本控制器&#xff1b; 所謂的版本控制器&#xff0c;就是能夠了解到一個文件的歷史記錄&#xff08;修改記錄&#xff09;&#xff1b;簡單來說就是記錄每一次的改動和版本迭代的一個管理系統&#xff0c;同…