基于生產-消費模式,使用Channel進行文件傳輸(Tcp方式)

Client端:

#region 多文件傳輸
public class FileMetadata
{public string FileName { get; set; }public long FileSize { get; set; }
}class Program
{const int PORT = 8888;const int BUFFER_SIZE = 60 * 1024 * 1024;//15s-50  25s-64 33s-32 27s-50 31s-40 25s-60const int MAX_CHANNEL_CAPACITY = 1000;static async Task Main(){Console.WriteLine($"Client ready to send file ...");Stopwatch stopwatch = new Stopwatch();stopwatch.Start();var folderPath = @"D:\cuda";//"D:\TestImage\imagesbaiyou";await SendFolderAsync(folderPath, "192.168.10.147");stopwatch.Stop();Console.WriteLine($"Client Transfer file need {TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds)} Milliseconds");Console.ReadKey();}static async Task SendFolderAsync(string folderPath, string server){using var client = new TcpClient();await client.ConnectAsync(server, PORT);using var stream = client.GetStream();int i = 1;foreach (var filePath in Directory.GetFiles(folderPath)){await SendFileAsync(filePath, stream);Console.WriteLine($"Send file {i++} ...");}}static async Task SendFileAsync(string filePath, NetworkStream stream){var fileInfo = new FileInfo(filePath);var metadata = new FileMetadata{FileName = fileInfo.Name,FileSize = fileInfo.Length};// 發送元數據var metaJson = JsonSerializer.Serialize(metadata);var metaBytes = Encoding.UTF8.GetBytes(metaJson);await stream.WriteAsync(BitConverter.GetBytes(metaBytes.Length));await stream.WriteAsync(metaBytes);// 創建傳輸通道var channel = Channel.CreateBounded<byte[]>(MAX_CHANNEL_CAPACITY);var readTask = FileToChannelAsync(filePath, channel.Writer);var sendTask = ChannelToNetworkAsync(channel.Reader, stream);await Task.WhenAll(readTask, sendTask);}static async Task FileToChannelAsync(string path, ChannelWriter<byte[]> writer){await using var fs = new FileStream(path, FileMode.Open);var buffer = new byte[BUFFER_SIZE];int bytesRead;while ((bytesRead = await fs.ReadAsync(buffer)) > 0){var chunk = new byte[bytesRead];Buffer.BlockCopy(buffer, 0, chunk, 0, bytesRead);await writer.WriteAsync(chunk);}writer.Complete();}static async Task ChannelToNetworkAsync(ChannelReader<byte[]> reader, NetworkStream stream){await foreach (var chunk in reader.ReadAllAsync()){await stream.WriteAsync(BitConverter.GetBytes(chunk.Length));await stream.WriteAsync(chunk);}}
}#endregion

Server端:

 #region 多文件傳輸2/*優化性能 7.7GB 文件 平均時間約15s完成接受和傳送傳輸時間和硬盤讀寫速度以及網絡硬件成正比關系測試該電腦本地傳輸速度約15s,固態硬盤將其傳輸到2.0的U盤當中,傳輸573MB的圖像約46s時間, 和單圖直接拷貝的時間差不多±1s的時間*/public class FileMetadata{public string FileName { get; set; }public long FileSize { get; set; }}class Program{const int PORT = 8888;const string SAVE_DIR = @"C:\Users\Leio\Desktop\ServerDownloads";const int BUFFER_SIZE = 1024 * 1024;const int MAX_CHANNEL_CAPACITY = 1000;static Stopwatch stopwatch = new Stopwatch();static async Task Main(){Directory.CreateDirectory(SAVE_DIR);var listener = new TcpListener(IPAddress.Any, PORT);listener.Start();Console.WriteLine("Server started,waiting client connect ...");while (true){var client = await listener.AcceptTcpClientAsync();_ = ProcessClientAsync(client);}}static async Task ProcessClientAsync(TcpClient client){stopwatch.Restart();using (client)using (var stream = client.GetStream()){try{while (true){// 讀取元數據var metaSize = BitConverter.ToInt32(await ReadExactlyAsync(stream, 4));var metadata = JsonSerializer.Deserialize<FileMetadata>(Encoding.UTF8.GetString(await ReadExactlyAsync(stream, metaSize)));// 創建傳輸通道var channel = Channel.CreateBounded<byte[]>(MAX_CHANNEL_CAPACITY);var savePath = Path.Combine(SAVE_DIR, metadata.FileName);// 啟動并行任務var receiveTask = ReceiveFileDataAsync(stream, channel.Writer, metadata.FileSize);var saveTask = SaveFileAsync(channel.Reader, savePath);await Task.WhenAll(receiveTask, saveTask);Console.WriteLine($"File saved: {savePath}");//totalTime += stopwatch.ElapsedMilliseconds;}}catch (EndOfStreamException){Console.WriteLine("Connection closed by client");}}stopwatch.Stop();Console.WriteLine($"Client Transfer file need {TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds)} s");}static async Task ReceiveFileDataAsync(NetworkStream stream,ChannelWriter<byte[]> writer,long totalSize){try{long remaining = totalSize;while (remaining > 0){var chunkSize = BitConverter.ToInt32(await ReadExactlyAsync(stream, 4));var chunkData = await ReadExactlyAsync(stream, chunkSize);await writer.WriteAsync(chunkData);remaining -= chunkSize;}}finally{writer.Complete();}}static async Task SaveFileAsync(ChannelReader<byte[]> reader, string savePath){await using var fs = new FileStream(savePath, FileMode.Create);await foreach (var chunk in reader.ReadAllAsync()){await fs.WriteAsync(chunk);}}static async Task<byte[]> ReadExactlyAsync(NetworkStream stream, int count){var buffer = new byte[count];int totalRead = 0;while (totalRead < count){var read = await stream.ReadAsync(buffer, totalRead, count - totalRead);if (read == 0) throw new EndOfStreamException();totalRead += read;}return buffer;}}#endregion

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

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

相關文章

【后端高階面經:Elasticsearch篇】39、Elasticsearch 查詢性能優化:分頁、冷熱分離與 JVM 調優

一、索引設計優化:構建高效查詢的基石 (一)分片與副本的黃金配置 1. 分片數量計算模型 # 分片數計算公式(單分片建議30-50GB) def calculate_shards(total_data_gb, single_shard_gb=30):return max

學習路之PHP--easyswoole3.3安裝入門

學習路之PHP--easyswoole安裝入門 一、安裝swoole擴展二、安裝easyswoole三、指定PHP版本安裝四、啟動swoole五、EasySwoole的入門學習如果報&#xff1a;not controller class match 六、學習推薦&#xff1a; 0、centos 7、php7.2.33、easyswoole 3.3 一、安裝swoole擴展 二、…

Ad Hoc

什么是 Ad Hoc&#xff1f; Ad hoc 一詞源于拉丁語&#xff0c;意為“為此目的”或“為此特定原因”。一般來講&#xff0c;它指的是為解決某一特定問題或任務&#xff08;而非為了廣泛重復應用&#xff09;而設計的行動、解決方案或組合。在加密貨幣和區塊鏈領域&#xff0c;…

Lines of Thought in Large Language Models

Lines of Thought in Large Language Models 《Lines of Thought in Large Language Models》(大語言模型中的思維鏈)聚焦于分析大語言模型(LLMs)在生成文本時,其內部向量軌跡的統計特性。 核心目標是揭示LLMs復雜的“思維過程”(即文本生成時的隱藏狀態變化)能否被簡…

npm/yarn/pnpm安裝時Sharp模塊報錯解決方法

在安裝依賴模塊時&#xff0c;npm/yarn/pnpm安裝時Sharp模塊報錯解決方法。 打開源代碼發現&#xff1a;使用的下載地址是github地址&#xff0c;就是因為國內經常無法訪問github造成的。 解決辦法&#xff1a; 把涉及到的下載包設置不要從github上下載&#xff0c;設置成淘寶…

基于CEEMDAN-Transformer-BiLSTM的多特征風速氣候預測的完整實現方案及PyTorch源碼解析

基于CEEMDAN-Transformer-BiLSTM的多特征風速氣候預測的完整實現方案及PyTorch源碼解析 一、模型架構設計 1.1 整體框架 該模型采用三級架構設計&#xff08;圖1&#xff09;&#xff1a; CEEMDAN分解層&#xff1a;對非平穩風速序列進行自適應分解多模態特征融合模塊&#…

ubuntu24.04啟用fcitx 5

在ubuntu24.04中啟用fcitx 5 ubuntu24.04系統自帶三種鍵盤輸入法系統&#xff1a; IBusFcitx 5XIM 系統默認使用的是IBus,這個拼音輸入少了一些智能的味道&#xff0c;比較影響輸入體驗。換用Fcitx 5后&#xff0c;加上搜狗細胞詞庫&#xff0c;感覺很絲滑&#xff0c;特記錄…

【HTML/CSS面經】

HTML/CSS面經 HTML1. script標簽中的async和defer的區別2. H5新特性&#xff08;1 標簽語義化&#xff08;2 表單功能增強&#xff08;3 音頻和視頻標簽&#xff08;4 canvas和svg繪畫&#xff08;5 地理位置獲取&#xff08;6 元素拖動API&#xff08;7 Web Worker&#xff08…

Dolphin文檔解析從理論到實踐——保姆級教程

論文&#xff1a;https://arxiv.org/abs/2505.14059 代碼&#xff1a;github.com/bytedance/Dolphin 2025年5月&#xff0c;字節開源了文檔解析Dolphin&#xff0c;讓文檔解析效率提升83%。本文將深入解析字節跳動最新開源的Dolphin模型&#xff0c;先看理論再實戰體驗。 現實…

Web3怎么本地測試連接以太坊?

ETHEREUM_RPC_URLhttps://sepolia.infura.io/v3/你的_INFURA_API_KEY 如果你沒有 Infura Key&#xff0c;注冊 Infura 或 Alchemy&#xff0c;拿一個免費測試網節點就行&#xff1a; Infura&#xff1a;https://infura.io Alchemy&#xff1a;Alchemy - the web3 developme…

深化生態協同,寧盾身份域管完成與拓波軟件兼容互認證

在信創產業蓬勃發展的浪潮下&#xff0c;行業生態的兼容適配決定了信創產品是否好用。近日&#xff0c;寧盾身份域管與拓波軟件 TurboEX 郵件系統完成兼容互認證。測試結果顯示寧盾身份域管&#xff08;信創版&#xff09;與 TurboEX 郵件服務器軟件相互良好兼容&#xff0c;運…

HDFS存儲原理與MapReduce計算模型

HDFS存儲原理 1. 架構設計 主從架構&#xff1a;包含一個NameNode&#xff08;主節點&#xff09;和多個DataNode&#xff08;從節點&#xff09;。 NameNode&#xff1a;管理元數據&#xff08;文件目錄結構、文件塊映射、塊位置信息&#xff09;&#xff0c;不存儲實際數據…

Function calling的過程

文章目錄 逐段講清 **LLM Function Calling&#xff08;函數調用&#xff09;** 的典型鏈路。1. 角色與概念 | Actors & Concepts2. 全流程時序 | End-to-End Sequence3. 關鍵細節 | Key Implementation Notes4. 最小可用示例&#xff08;偽代碼&#xff09; | Minimal Exa…

GlobalExceptionHandler 自定義異常類 + 處理validation的異常

在 Spring Boot 項目中&#xff0c;?自定義異常通常用于處理特定的業務邏輯錯誤&#xff0c;并結合全局異常處理器&#xff08;ControllerAdvice&#xff09;統一返回結構化的錯誤信息。 一.全局異常處理器&#xff1a; 1. 自定義異常類? 定義一個繼承自 RuntimeExceptio…

軟件測試過程中如何定位BUG

在軟件測試過程中&#xff0c;定位BUG是確保軟件質量的關鍵環節。有效的BUG定位不僅能幫助開發人員快速修復問題&#xff0c;還能提升整個軟件項目的效率。以下是軟件測試中定位BUG的系統性方法和策略&#xff1a; 一、復現BUG 步驟&#xff1a; 收集信息&#xff1a;記錄BUG…

如何優化Elasticsearch的搜索性能?

優化 Elasticsearch 的搜索性能需要從索引設計、查詢優化、硬件配置和集群調優等多方面入手。以下是系統化的優化策略和實操建議: 一、索引設計優化 1. 合理設置分片數 分片大小:單個分片建議 10-50GB(超過50GB會影響查詢性能)。分片數量: 總分片數 ≤ 節點數 1000(避免…

臺式電腦CPU天梯圖_2025年臺式電腦CPU天梯圖

CPU的選擇絕對是重中之重,它關乎了一臺電腦性能好壞。相信不少用戶,在挑選CPU的時候不知道誰強誰弱,尤其是intel和AMD兩款CPU之間。下面通過2025年臺式電腦CPU天梯圖來了解下這兩款cpu. 2025年臺式電腦CPU天梯圖 2025年臺式電腦CPU天梯圖包含了老舊型號以及12代、13代、14代…

HarmonyOS_ArkTs_API(1)

HarmonyOS_ArkTs_API(1) 概述 此API服務模塊是獨自開發的應用程序的核心骨架&#xff0c;提供了鴻蒙OS ArkTS客戶端組件和Java Spring Boot后端之間的強大通信接口。該模塊采用清晰的架構方法處理所有HTTP請求、響應解析和錯誤處理&#xff0c;確保系統各部分間通信的一致性和…

matlab雷達定位仿真

一、邊掃描邊跟蹤雷達仿真 邊掃描邊跟蹤&#xff08;BISTAR&#xff09;雷達仿真是一種實時雷達信號處理的技術&#xff0c;用于模擬雷達系統的操作過程&#xff0c;特別是那些具備連續掃描能力的雷達。它的基本原理和流程可以分為以下幾個步驟&#xff1a; &#xff08;1&…

互斥鎖、自旋鎖、讀寫鎖、悲觀鎖、樂觀鎖的應用場景

一&#xff1a;并發 1.1MySQL并發事務訪問相同記錄 &#xff08;1&#xff09;讀-讀 不影響 &#xff08;2&#xff09;寫-寫 寫的數據需要一個一個來&#xff0c;排隊執行 &#xff08;3&#xff09;讀-寫 兩次讀…