C# TCP的方式 实现上传文件
以下是基于C#的TCP文件上传功能的完整实现代码,包含服务端和客户端的关键实现细节。代码采用分块传输机制,支持大文件传输,并包含必要的异常处理和资源管理。
服务端代码实现
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;public class FileServer
{private const int Port = 12345;private const int BufferSize = 81920; // 80KB缓冲区public static void StartServer(){TcpListener listener = new TcpListener(IPAddress.Any, Port);listener.Start();Console.WriteLine($"服务器已启动,等待客户端连接...");try{using (TcpClient client = listener.AcceptTcpClient()){Console.WriteLine("客户端已连接。");NetworkStream stream = client.GetStream();// 读取文件信息头(文件名+文件大小)byte[] headerBuffer = new byte[1024];int headerBytesRead = stream.Read(headerBuffer, 0, headerBuffer.Length);string fileInfo = Encoding.UTF8.GetString(headerBuffer, 0, headerBytesRead);string[] infoParts = fileInfo.Split('|');string fileName = infoParts[0];long fileSize = long.Parse(infoParts[1]);// 创建保存路径string savePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);using (FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write)){byte[] buffer = new byte[BufferSize];long totalReceived = 0;int bytesRead;while (totalReceived < fileSize &&(bytesRead = stream.Read(buffer, 0, (int)Math.Min(buffer.Length, fileSize - totalReceived))) > 0){fileStream.Write(buffer, 0, bytesRead);totalReceived += bytesRead;Console.WriteLine($"已接收: {totalReceived}/{fileSize} 字节 ({(totalReceived * 100 / fileSize)}%)");}}Console.WriteLine("文件接收完成。");}}catch (Exception ex){Console.WriteLine($"错误: {ex.Message}");}finally{listener.Stop();}}
}
客户端代码实现
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;public class FileClient
{private const string ServerIP = "127.0.0.1";private const int Port = 12345;private const int BufferSize = 81920; // 80KB缓冲区public static void UploadFile(string filePath){if (!File.Exists(filePath)){Console.WriteLine("文件不存在!");return;}FileInfo fileInfo = new FileInfo(filePath);long fileSize = fileInfo.Length;try{using (TcpClient client = new TcpClient()){client.Connect(ServerIP, Port);NetworkStream stream = client.GetStream();// 发送文件信息头(文件名|文件大小)string header = $"{fileInfo.Name}|{fileSize}";byte[] headerBytes = Encoding.UTF8.GetBytes(header);stream.Write(headerBytes, 0, headerBytes.Length);// 分块发送文件数据using (FileStream fileStream = File.OpenRead(filePath)){byte[] buffer = new byte[BufferSize];int bytesRead;long totalSent = 0;while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0){stream.Write(buffer, 0, bytesRead);totalSent += bytesRead;Console.WriteLine($"已发送: {totalSent}/{fileSize} 字节 ({(totalSent * 100 / fileSize)}%)");}}}Console.WriteLine("文件上传完成。");}catch (Exception ex){Console.WriteLine($"错误: {ex.Message}");}}
}
关键功能说明
-
文件信息头传输
客户端在发送文件前,先发送包含文件名和文件大小的头部信息(格式:文件名|文件大小
),服务端解析后创建目标文件。此设计避免了大文件内存占用过高的问题。 -
分块传输机制
使用固定大小缓冲区(如80KB)分块读写文件,避免一次性加载大文件导致内存溢出,同时支持断点续传扩展。 -
异常处理
包含网络中断、文件不存在等异常捕获,确保程序健壮性。 -
进度显示
实时显示传输进度百分比,提升用户体验。
使用示例
// 服务端启动
FileServer.StartServer();// 客户端上传文件
FileClient.UploadFile("C:\\test\\largefile.zip");
扩展建议
-
断点续传
可在服务端记录已接收的字节数,客户端支持从断点处继续发送(需在头部增加校验和字段)。 -
异步传输
使用BeginRead
/BeginWrite
或async/await
优化性能,避免阻塞主线程。 -
加密传输
添加TLS/SSL加密层,保障传输安全性。 -
多线程处理
服务端支持同时处理多个客户端连接,提升并发能力。
以上代码可满足基础文件传输需求。实际应用中需根据具体场景调整缓冲区大小、超时设置等参数。