基于Python實現(控制臺)UDP傳輸協議的可靠文件傳輸工具

LFTP Design

簡介

LFTP是一個采用python3實現的基于UDP傳輸協議的可靠文件傳輸工具

特點

  • 基于UDP
    • 采用python3編程語言,socket的類型均為socket(AF_INET,SOCK_DGRAM)實現
  • 實現100%可靠性傳輸
    • 使用SR(選擇重傳)協議保證所有報文都正確接收
  • 實現流量控制
    • 使用接收者通知發送者接收緩存大小來反饋發送窗口大小
  • 實現擁塞控制
    • 根據網絡情況動態調整發送窗口大小。
  • 實現并發傳輸
    • 使用多個服務線程,滿足多個用戶同時上傳或者下載的需求
  • 支持大文件傳輸且不需要過多內存
    • 切塊傳輸

具體設計

項目結構:

項目樹:

.
├── docs
│ ├── Design-doc.md
│ └── Test-doc.md
├── README.md
└── src├── Client│ └── client.py   # 客戶端├── Helper│ ├── __init__.py│ ├── LFTPMessage.py    # 封裝傳遞的包│ ├── LFTPRecvWindow.py # 接收窗口│ └── LFTPSendWindow.py # 發送端口├── Server│ └── server.py   # 服務端└── Utils└── Log.py      # 記錄日志

基本流程

流程參考FTP被動模式,首先客戶端會獲取一個隨機端口(python的socket指定),然后向我們指定定的服務端端口發送請求命令,然后服務端主控制線程會新開一個數據線程,分配一個數據傳輸端口,并且把端口號發送給客戶端,然后客戶端向這個數據傳輸端口獲取文件數據或者發送文件數據。這種方式保證了多個客戶端可以同時連接服務器進行數據傳輸。

客戶端上傳文件到服務端

具體工作過程:

  • 客戶端向服務端請求發送文件,獲取服務端的數據端口
  • 服務端接收到發送文件請求,從空閑的地址池中選擇一個端口,新開一個數據線程,在這個端口上監聽接收的數據
  • 客戶端接收到服務端傳來的數據端口,向該數據端口發起連接
  • 若連接成功,客戶端向服務端開始發送文件分組信息
  • 服務端接收到相應的分組,發回相應的ACK確認(采用累積確認)
  • 客戶端接收到相應的ACK,做出調整
  • 客戶端接收到所有分組的ACK,結束進程
  • 服務端超時5s(有可能需要ACK相應的信息,即使收到了全部的包)之后同樣關閉端口
客戶端從服務器下載文件

下載的過程和上傳的過程類似,只是在建立連接之后,由數據方,也就是服務端開始發數據分組

  • 客戶端向服務端請求發送文件,獲取服務端的數據端口
  • 服務端接收到發送文件請求,從空閑的地址池中選擇一個端口,新開一個數據線程,在這個端口上監聽接收的數據
  • 客戶端接收到服務端傳來的數據端口,向該數據端口發起連接
  • 若連接成功,服務端向客戶端開始發送文件分組信息
  • 客戶端接收到相應的分組,發回相應的ACK確認(采用累積確認)
  • 服務端接收到相應的ACK,做出調整(cwnd和rwnd)
  • 服務端接收到所有分組的ACK,結束該服務線程,關閉端口
  • 客戶端超時5s(有可能需要ACK相應的信息,即使收到了全部的包)之后結束進程

相關細節實現

文件相關信息的接收和發送

這里的文件相關信息指示的是文件名稱或文件大小等信息,原先打算在每個包的首部加上該字段,存儲文件相關信息,后來發現可以在三次握手期間將文件信息發與服務端(或者從服務端獲取該相關信息)

可靠性的實現

這里參考TCP的重傳和確認,采用SR(選擇重傳)和累積確認的結合方式,當收取到相應的數據包,接收方會發送ACK包,與SR不同的是,這里ACK包中的確認號ACKnum是選擇最小的未接收序列號。

擁塞控制實現

在接收到ACK的時候:

  • 正確的ACK,增加窗口大小:
    • 慢啟動階段:cwnd <= ssthresh: cwnd = cwnd + 1
    • 擁塞避免階段:cwnd > ssthresh: cwnd = cwnd + 1/cwnd
  • 冗余的ACK,三次冗余將重傳 + 減少窗口大小
    • ssthresh = cwnd / 2
    • cwnd = cwnd/2 + 3
  • 超時,重傳 + 減少窗口大小
    • ssthresh = cwnd / 2
    • cwnd = 1
流量控制實現

在ACK確認分組信息頭部加上接收窗口空余數(可用數),發送方接收到該確認分組之后將根據該字段,動態調整發送窗口的長度

并發多客戶上傳或下載的實現

服務端會有一個主控制線程,每受到新的客戶端的請求(UPLOAD/DOWNLOAD),它都會從空閑端口池中取出空閑端口,新建一個數據線程去監聽該端口,然后主控制線程會告訴客戶端去跟新的數據線程連接并傳遞信息。

大文件讀寫的實現

python3讀取文件的函數file.read(size),已經自動幫我們做了緩存機制,所以我們可以直接進行讀寫而不必進行數據分塊處理,但需要注意的是,不能一次性read()整個文件,不然會將整個文件讀入內存中,大文件會直接將內存撐爆,而要使用read(size),通過大小為size的緩存,實現對文件的分塊讀取(每次只讀取size)。

測試

局域網下進行測試

服務端

命令行開啟服務(默認跑在123456端口)

$ python3 server.py

客戶端

命令錯誤會有相應的提示信息

發送數據
使用指令LFTP lsend 127.0.0.1 filepath 進行上傳相應的文件

這里我上傳了一個幾十MB的pdf文件:

上傳結束:

對比服務端和客戶端的文件大小:

可以發現客戶端和服務端的文件子節數相同,上傳成功

接收數據
使用指令LFTP lget 127.0.0.1 filename 進行下載相應的文件

這里我刪除剛才上傳的了的pdf文件,再進行下載:

下載結束:

對比服務端和客戶端的文件大小:

可以發現客戶端和服務端的文件子節數相同,下載成功

測試并行下載

上圖可以看出服務端支持兩個客戶端同時進行文件的下載

互聯網下進行測試

測試環境

服務器:騰訊云

配置:2核2G

帶寬:上行1Mbps,下行8Mbps

系統:ubuntu 16.04 64位

運行環境:Python3

公網IP:119.29.204.118 (廣州)

服務端

命令行開啟服務(默認跑在123456端口)

$ python3 server.py

客戶端

發送數據
使用指令LFTP lsend 119.29.204.118 filepath 進行上傳相應的文件

跟在局域網下相似,這里我上傳了一個幾十MB的pdf文件:

上傳結束

對比一下接收到的文件和源文件

可以發現客戶端和服務端的文件子節數相同,上傳成功

接收數據
使用指令LFTP lget 119。29.204.118 filename 進行下載相應的文件

這里我刪除剛才上傳的了的pdf文件,再進行下載:

下載結束:

對比服務端和客戶端的文件大小:

可以發現客戶端和服務端的文件子節數相同,下載成功

測試并行下載
在局域網下測試:

上圖可以看出服務端成功支持兩個客戶端同時進行文件的下載

擁塞控制測試

因為局域網內的帶寬過大,難以看出擁塞控制測試的效果,因此這里使用互聯網環境,在云服務器上1Mbps的帶寬下同時下載文件

首先讓一個客戶端先開啟下載,可以達到300KB/s的速度:

然后,再連接一個客戶端,可以看到,此時速度都降低到150KB/s的速度。約為原來的1/2:

流量控制測試

因為文件寫入的速度遠快于數據在網絡中的傳輸數度,流量控制并沒有很明顯的表現,所以此處并沒有流量控制測試的相關截圖。

大文件下載測試

這里在局域網下進行了大文件測試


可以看出,即使上傳超過4GB,內存并沒有過多占有,這里只是占用了 0.1% 的內存.

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

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

相關文章

【Go-7】面向對象編程

7. 面向對象編程 面向對象編程&#xff08;Object-Oriented Programming&#xff0c;簡稱OOP&#xff09;是一種編程范式&#xff0c;通過將數據和行為封裝在對象中&#xff0c;以提高代碼的可重用性、可維護性和擴展性。雖然Go語言不像傳統的OOP語言&#xff08;如Java、C&am…

PHP語法基礎篇(六):數組

PHP 中的數組實際上是一個有序映射。映射是一種把 values 關聯到 keys 的類型。此類型針對多種不同用途進行了優化&#xff1b;它可以被視為數組、列表&#xff08;向量&#xff09;、哈希表&#xff08;映射的實現&#xff09;、字典、集合、堆棧、隊列等等。本篇文章將記錄數…

GitHub Actions 的深度解析與概念介紹

GitHub Actions 核心定義 Git Actions 是 GitHub 原生提供的 自動化工作流引擎&#xff0c;允許開發者在代碼倉庫中直接創建、測試、部署代碼。其本質是通過事件驅動&#xff08;Event-Driven&#xff09;的自動化管道&#xff0c;將軟件開發中的重復任務抽象為可編排的流程。…

TestCafe 全解析:免費開源的 E2E 測試解決方案實戰指南

在2025年的數字化浪潮中&#xff0c;Web應用的穩定性和用戶體驗成為企業競爭的關鍵&#xff0c;而端到端&#xff08;E2E&#xff09;測試則是確保質量的“守護者”&#xff01;想象一下&#xff0c;您的電商平臺因表單錯誤導致用戶流失&#xff0c;或者支付流程因瀏覽器兼容性…

[CVPR 2025] 高效無監督Prompt與偏好對齊驅動的半監督醫學分割

CVPR 2025 | 優化SAM&#xff1a;高效無監督Prompt與偏好對齊驅動的半監督醫學分割 論文信息 標題&#xff1a;Enhancing SAM with Efficient Prompting and Preference Optimization for Semi-supervised Medical Image Segmentation作者&#xff1a;Aishik Konwer, Zhijian…

【C++】責任鏈模式

目錄 一、模式核心概念與結構二、C++ 實現示例:員工請假審批系統三、責任鏈模式的關鍵特性四、應用場景五、責任鏈模式與其他設計模式的關系六、C++ 標準庫中的責任鏈模式應用七、優缺點分析八、實戰案例:Web 請求過濾器鏈九、實現注意事項如果這篇文章對你有所幫助,渴望獲得…

dp進階,樹形背包(dfs+01)

顧名思義&#xff0c;就是在對樹進行搜索的時候&#xff0c;由于限制了子節點選根節點必選和節點數限制&#xff0c;所以需要額外利用背包來維護最大值 假設根節點就是0&#xff0c;我們很容易 發現&#xff0c;這就是一個正常的樹求和&#xff0c;但是限制了節點數量&#xf…

微信小程序安卓手機輸入框文字飄出輸入框

最近在開發微信小程序遇到一個問題&#xff0c;安卓手機輸入框文字飄出輸入框&#xff0c;但是ios系統的手機則正常。 使用情景&#xff1a;做了一個彈窗&#xff0c;彈窗內是表單&#xff0c;需要填寫一些信息&#xff0c;但是在填寫信息時光標不顯示&#xff0c;輸入的內容飄…

3 大語言模型預訓練數據-3.2 數據處理-3.2.2 冗余去除——3.后綴數組(Suffix Array)在大模型數據去重中的原理與實戰

后綴數組&#xff08;Suffix Array&#xff09;在大模型數據去重中的原理與實戰 一、后綴數組的核心原理與數據結構二、后綴數組去重的核心流程1. **文檔預處理與合并**2. **構建后綴數組**3. **計算最長公共前綴&#xff08;LCP&#xff09;數組**4. **基于LCP檢測重復文檔** …

數據庫外連接詳解:方式、差異與關鍵注意事項

&#x1f504; 數據庫外連接詳解&#xff1a;方式、差異與關鍵注意事項 外連接用于保留至少一個表的全部行&#xff0c;即使另一表無匹配記錄。以下是三種外連接方式的深度解析&#xff1a; &#x1f50d; 一、外連接的三種類型 1. 左外連接 (LEFT OUTER JOIN) 作用&#xf…

vscode把less文件生成css文件配置,設置生成自定義文件名稱和路徑

1.下載less插件 在插件市場搜索 less 2.設置生成配置 3.修改out屬性 "less.compile": {"compress": false, // 是否刪除多余空白字符 一行顯示[壓縮]"sourceMap": false, // 是否創建文件目錄樹&#xff0c;true的話會自動生成一個 .css.map …

探索相機成像的奧秘 - 齊次坐標、徑向失真和圖像傳感器傾斜

引言 大家好&#xff01;今天我們將一起探索相機成像背后的一些關鍵技術概念&#xff1a;齊次坐標、徑向失真和圖像傳感器傾斜。這些概念對于理解相機如何捕捉和處理圖像至關重要。我們將通過簡單易懂的語言和嚴謹的公式來詳細解釋這些概念。 齊次坐標&#xff08;Homogeneou…

校企協同育人,智慧養老實訓基地助力人才就業無憂

隨著我國人口老齡化程度不斷加深&#xff0c;智慧養老產業蓬勃發展&#xff0c;對專業人才的需求日益迫切。校企協同打造智慧養老實訓基地&#xff0c;成為解決人才供需矛盾、提升人才培養質量的重要途徑。通過科學的建設方案&#xff0c;智慧養老實訓基地能夠為學生提供實踐平…

從需求到落地:一個AI訓練平臺的售前全流程復盤

目錄 一、項目背景:客戶要建自己的AI訓練平臺 二、需求梳理三板斧:并發量、存儲帶寬、模型種類 1. 并發訓練量 2. 存儲帶寬需求 3. 模型類型與參數規模 三、解決方案設計:GPU選型 + 高速網絡 + 存儲架構 ? GPU服務器選型 ? 網絡與通信架構 ? 存儲與數據緩存 四…

織夢DedeCMS轉WordPress

最近&#xff0c;有個用戶找模板兔遷移網站&#xff0c;源站用的dede&#xff0c;需要轉成wp&#xff0c;文章數量大概7000-8000篇&#xff0c;其中有個需求是保證舊文章的鏈接有效&#xff0c;在wp上的新文章與舊文章的鏈接類型不一樣&#xff0c;所以這涉及到偽靜態來處理跳轉…

installGo.sh

#!/bin/bash # 檢查是否以root用戶運行 if [ "$(id -u)" -ne 0 ]; then echo "請使用root權限運行此腳本" exit 1 fi # 檢查是否安裝了必要的工具 for cmd in curl wget tar; do if ! command -v $cmd &> /dev/null; then echo…

【技術難題】el-table的全局數據排序實現示例,不受分頁影響,以及異步請求帶來的頁面渲染問題

參考鏈接:https://blog.csdn.net/qq_35770559/article/details/131183121 問題代碼 編輯頁面detail.vue <el-form title="列表信息" name="detail"><el-form><el-form-item><el-buttontype="cyan"icon="el-icon-p…

非功能測試

非功能測試范疇&#xff1a;界面測試&#xff0c;易用性測試&#xff0c;兼容性測試&#xff0c;文檔測試&#xff0c;安裝/卸載測試等等 界面測試 1.窗體界面測試 1.窗體定義&#xff1a;指整個軟件窗口&#xff0c;也可稱為窗口&#xff0c;是界面測試的基本單位 2.控件分…

一起endpoint迷路的問題排查總結

今天上班&#xff0c;一到工位上&#xff0c;就有同事和我說有客戶反映自己的容器的一些指標在監控平臺不上報了&#xff0c;我當時一看機器所在的監控&#xff0c;發現確實是這樣 確實存在某個點開始數據就沒了&#xff0c;主要這個點當時也沒有任何的操作變更&#xff0c;于…

官方 Linker Scripts 語法和規則解析(2)

系列文章目錄 官方 Linker Scripts 語法和規則解析&#xff08;1&#xff09; 官方 Linker Scripts 語法和規則解析&#xff08;2&#xff09; 官方 Linker Scripts 語法和規則解析&#xff08;3&#xff09; 鏈接腳本(Linker Scripts)語法和規則解析(自官方手冊) 7.9. 鏈接腳…