//sender; class FileSender {private readonly HttpClient _httpClient;public FileSender(){_httpClient = new HttpClient{Timeout = TimeSpan.FromHours(2) // 2小时超时 };}public async Task<bool> SendFileAsync(string filePath, string serverUrl,IProgress<UploadProgress> progress = null){if (!File.Exists(filePath)){Console.WriteLine($"文件不存在: {filePath}");return false;}var fileInfo = new FileInfo(filePath);var fileName = Path.GetFileName(filePath);Console.WriteLine($"开始上传文件: {fileName}");Console.WriteLine($"文件大小: {FormatFileSize(fileInfo.Length)}");try{await using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)){var content = new ProgressStreamContent(fileStream, progress, fileName);var response = await _httpClient.PostAsync(serverUrl, content);if (response.IsSuccessStatusCode){var result = await response.Content.ReadAsStringAsync();Console.WriteLine($"上传成功: {result}");return true;}else{Console.WriteLine($"上传失败: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}");return false;}}}catch (Exception ex){Console.WriteLine($"上传过程中出错: {ex.Message}");return false;}}private string FormatFileSize(long bytes){string[] sizes = { "B", "KB", "MB", "GB", "TB" };int order = 0;double len = bytes;while (len >= 1024 && order < sizes.Length - 1){order++;len /= 1024;}return $"{len:0.##} {sizes[order]}";} }public class UploadProgress {public long BytesRead { get; set; }public long TotalBytes { get; set; }public double ProgressPercentage => TotalBytes > 0 ? (BytesRead * 100.0) / TotalBytes : 0;public double Speed { get; set; } // bytes per second }class ProgressStreamContent : StreamContent {private readonly Stream _stream;private readonly IProgress<UploadProgress> _progress;private readonly string _fileName;private readonly long _totalBytes;private long _bytesRead;private readonly System.Diagnostics.Stopwatch _stopwatch;public ProgressStreamContent(Stream stream, IProgress<UploadProgress> progress, string fileName): base(stream){_stream = stream;_progress = progress;_fileName = fileName;_totalBytes = stream.Length;_bytesRead = 0;_stopwatch = System.Diagnostics.Stopwatch.StartNew();}protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context){var buffer = new byte[81920]; // 80KB bufferint read;while ((read = await _stream.ReadAsync(buffer, 0, buffer.Length)) > 0){await stream.WriteAsync(buffer, 0, read);_bytesRead += read;// 计算速度var elapsedSeconds = _stopwatch.Elapsed.TotalSeconds;var speed = elapsedSeconds > 0 ? _bytesRead / elapsedSeconds : 0;_progress?.Report(new UploadProgress{BytesRead = _bytesRead,TotalBytes = _totalBytes,Speed = speed});}}protected override bool TryComputeLength(out long length){length = _totalBytes;return true;} }//Receiverclass FileReceiver{private readonly HttpListener _listener;private readonly string _saveDirectory;public FileReceiver(string prefix, string saveDirectory){_listener = new HttpListener();_listener.Prefixes.Add(prefix);_saveDirectory = saveDirectory;Directory.CreateDirectory(saveDirectory);}public async Task StartAsync(){_listener.Start();Console.WriteLine("文件接收服务已启动...");Console.WriteLine("等待文件上传...");while (true){try{var context = await _listener.GetContextAsync();_ = Task.Run(() => ProcessRequestAsync(context));}catch (Exception ex){Console.WriteLine($"接收错误: {ex.Message}");}}}private async Task ProcessRequestAsync(HttpListenerContext context){var request = context.Request;var response = context.Response;try{if (request.HttpMethod == "POST"){// 获取文件名var fileName = request.Headers["X-FileName"] ?? "unknown_file.dat";var filePath = Path.Combine(_saveDirectory, fileName);Console.WriteLine($"开始接收文件: {fileName}");var stopwatch = System.Diagnostics.Stopwatch.StartNew();// 流式接收文件await using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)){await request.InputStream.CopyToAsync(fileStream);}stopwatch.Stop();var fileInfo = new FileInfo(filePath);Console.WriteLine($"文件接收完成: {fileName}");Console.WriteLine($"文件大小: {FormatFileSize(fileInfo.Length)}");Console.WriteLine($"耗时: {stopwatch.Elapsed.TotalSeconds:F2} 秒");Console.WriteLine($"平均速度: {FormatFileSize((long)(fileInfo.Length / stopwatch.Elapsed.TotalSeconds))}/s");// 发送成功响应response.StatusCode = 200;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync("文件上传成功");}}else{response.StatusCode = 405;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync("只支持 POST 方法");}}}catch (Exception ex){Console.WriteLine($"处理请求时出错: {ex.Message}");response.StatusCode = 500;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync($"服务器错误: {ex.Message}");}}finally{response.Close();}}private string FormatFileSize(long bytes){string[] sizes = { "B", "KB", "MB", "GB", "TB" };int order = 0;double len = bytes;while (len >= 1024 && order < sizes.Length - 1){order++;len /= 1024;}return $"{len:0.##} {sizes[order]}";}public void Stop(){_listener?.Stop();_listener?.Close();}}
//sender using System.Net; using System.Text;namespace ConsoleApp13 {internal class Program{static async Task Main(string[] args){// 设置控制台输出编码为 UTF-8Console.OutputEncoding = Encoding.UTF8;// 设置控制台输入编码为 UTF-8Console.InputEncoding = Encoding.UTF8;Console.WriteLine("=== 大文件发送端 (ConsoleA) ===");// 配置string filePath = @"E:\KXWC\kxwc1.ts";string serverUrl = "http://localhost:8080/upload/";// 创建进度报告器var progress = new Progress<UploadProgress>(report =>{Console.SetCursorPosition(0, Console.CursorTop);Console.Write($"进度: {report.ProgressPercentage:F2}% | ");Console.Write($"已传输: {FormatFileSize(report.BytesRead)} / {FormatFileSize(report.TotalBytes)} | ");Console.Write($"速度: {FormatFileSize((long)report.Speed)}/s");Console.WriteLine();});var sender = new FileSender();try{var success = await sender.SendFileAsync(filePath, serverUrl, progress);if (success){Console.WriteLine("\n文件传输完成!");}else{Console.WriteLine("\n文件传输失败!");}}catch (Exception ex){Console.WriteLine($"\n传输过程中发生错误: {ex.Message}");}Console.WriteLine("按任意键退出...");Console.ReadKey();}static string FormatFileSize(long bytes){string[] sizes = { "B", "KB", "MB", "GB", "TB" };int order = 0;double len = bytes;while (len >= 1024 && order < sizes.Length - 1){order++;len /= 1024;}return $"{len:0.##} {sizes[order]}";}}class FileSender{private readonly HttpClient _httpClient;public FileSender(){_httpClient = new HttpClient{Timeout = TimeSpan.FromHours(2) // 2小时超时 };}public async Task<bool> SendFileAsync(string filePath, string serverUrl,IProgress<UploadProgress> progress = null){if (!File.Exists(filePath)){Console.WriteLine($"文件不存在: {filePath}");return false;}var fileInfo = new FileInfo(filePath);var fileName = Path.GetFileName(filePath);Console.WriteLine($"开始上传文件: {fileName}");Console.WriteLine($"文件大小: {FormatFileSize(fileInfo.Length)}");try{await using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)){var content = new ProgressStreamContent(fileStream, progress, fileName);var response = await _httpClient.PostAsync(serverUrl, content);if (response.IsSuccessStatusCode){var result = await response.Content.ReadAsStringAsync();Console.WriteLine($"上传成功: {result}");return true;}else{Console.WriteLine($"上传失败: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}");return false;}}}catch (Exception ex){Console.WriteLine($"上传过程中出错: {ex.Message}");return false;}}private string FormatFileSize(long bytes){string[] sizes = { "B", "KB", "MB", "GB", "TB" };int order = 0;double len = bytes;while (len >= 1024 && order < sizes.Length - 1){order++;len /= 1024;}return $"{len:0.##} {sizes[order]}";}}public class UploadProgress{public long BytesRead { get; set; }public long TotalBytes { get; set; }public double ProgressPercentage => TotalBytes > 0 ? (BytesRead * 100.0) / TotalBytes : 0;public double Speed { get; set; } // bytes per second }class ProgressStreamContent : StreamContent{private readonly Stream _stream;private readonly IProgress<UploadProgress> _progress;private readonly string _fileName;private readonly long _totalBytes;private long _bytesRead;private readonly System.Diagnostics.Stopwatch _stopwatch;public ProgressStreamContent(Stream stream, IProgress<UploadProgress> progress, string fileName): base(stream){_stream = stream;_progress = progress;_fileName = fileName;_totalBytes = stream.Length;_bytesRead = 0;_stopwatch = System.Diagnostics.Stopwatch.StartNew();}protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context){var buffer = new byte[81920]; // 80KB bufferint read;while ((read = await _stream.ReadAsync(buffer, 0, buffer.Length)) > 0){await stream.WriteAsync(buffer, 0, read);_bytesRead += read;// 计算速度var elapsedSeconds = _stopwatch.Elapsed.TotalSeconds;var speed = elapsedSeconds > 0 ? _bytesRead / elapsedSeconds : 0;_progress?.Report(new UploadProgress{BytesRead = _bytesRead,TotalBytes = _totalBytes,Speed = speed});}}protected override bool TryComputeLength(out long length){length = _totalBytes;return true;}} }//receiver using System.Net; using System.Text;namespace ConsoleApp14 {class Program{static async Task Main(string[] args){// 设置控制台输出编码为 UTF-8Console.OutputEncoding = Encoding.UTF8;// 设置控制台输入编码为 UTF-8Console.InputEncoding = Encoding.UTF8;Console.WriteLine("=== 大文件接收端 (ConsoleB) ===");// 配置string url = "http://localhost:8080/upload/";string saveDirectory = @"E:\";var receiver = new FileReceiver(url, saveDirectory);// 设置 Ctrl+C 处理Console.CancelKeyPress += (sender, e) =>{e.Cancel = true;Console.WriteLine("正在停止服务...");receiver.Stop();Environment.Exit(0);};try{await receiver.StartAsync();}catch (Exception ex){Console.WriteLine($"服务运行错误: {ex.Message}");}Console.WriteLine("按任意键退出...");Console.ReadKey();}}class FileReceiver{private readonly HttpListener _listener;private readonly string _saveDirectory;public FileReceiver(string prefix, string saveDirectory){_listener = new HttpListener();_listener.Prefixes.Add(prefix);_saveDirectory = saveDirectory;Directory.CreateDirectory(saveDirectory);}public async Task StartAsync(){_listener.Start();Console.WriteLine("文件接收服务已启动...");Console.WriteLine("等待文件上传...");while (true){try{var context = await _listener.GetContextAsync();_ = Task.Run(() => ProcessRequestAsync(context));}catch (Exception ex){Console.WriteLine($"接收错误: {ex.Message}");}}}private async Task ProcessRequestAsync(HttpListenerContext context){var request = context.Request;var response = context.Response;try{if (request.HttpMethod == "POST"){// 获取文件名var fileName = request.Headers["X-FileName"] ?? "unknown_file.dat";var filePath = Path.Combine(_saveDirectory, fileName);Console.WriteLine($"开始接收文件: {fileName}");var stopwatch = System.Diagnostics.Stopwatch.StartNew();// 流式接收文件await using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)){await request.InputStream.CopyToAsync(fileStream);}stopwatch.Stop();var fileInfo = new FileInfo(filePath);Console.WriteLine($"文件接收完成: {fileName}");Console.WriteLine($"文件大小: {FormatFileSize(fileInfo.Length)}");Console.WriteLine($"耗时: {stopwatch.Elapsed.TotalSeconds:F2} 秒");Console.WriteLine($"平均速度: {FormatFileSize((long)(fileInfo.Length / stopwatch.Elapsed.TotalSeconds))}/s");// 发送成功响应response.StatusCode = 200;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync("文件上传成功");}}else{response.StatusCode = 405;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync("只支持 POST 方法");}}}catch (Exception ex){Console.WriteLine($"处理请求时出错: {ex.Message}");response.StatusCode = 500;await using (var writer = new StreamWriter(response.OutputStream)){await writer.WriteAsync($"服务器错误: {ex.Message}");}}finally{response.Close();}}private string FormatFileSize(long bytes){string[] sizes = { "B", "KB", "MB", "GB", "TB" };int order = 0;double len = bytes;while (len >= 1024 && order < sizes.Length - 1){order++;len /= 1024;}return $"{len:0.##} {sizes[order]}";}public void Stop(){_listener?.Stop();_listener?.Close();}} }