基于C#实现TCP/UDP通信及文件传输

一、TCP通信实现

1. 服务器端(文件传输)

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class TcpFileServer {
    private const int Port = 12345;
    private const string BufferSize = 8192;

    public static void Start() {
        using (TcpListener listener = new TcpListener(IPAddress.Any, Port)) {
            listener.Start();
            Console.WriteLine($"服务器已启动,等待连接...");

            using (TcpClient client = listener.AcceptTcpClient())
            using (NetworkStream stream = client.GetStream()) {
                // 接收文件信息
                byte[] fileInfo = new byte[1024];
                int bytesRead = stream.Read(fileInfo, 0, fileInfo.Length);
                string fileName = Encoding.UTF8.GetString(fileInfo, 0, bytesRead).TrimEnd('\0');

                // 接收文件数据
                using (FileStream fs = new FileStream($"received_{fileName}", FileMode.Create)) {
                    byte[] buffer = new byte[BufferSize];
                    int totalBytes = 0;
                    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) {
                        fs.Write(buffer, 0, bytesRead);
                        totalBytes += bytesRead;
                        Console.WriteLine($"已接收: {totalBytes}字节");
                    }
                }
            }
        }
    }
}

2. 客户端(文件传输)

public class TcpFileClient {
    public static void SendFile(string filePath, string serverIp) {
        using (TcpClient client = new TcpClient(serverIp, 12345))
        using (NetworkStream stream = client.GetStream()) {
            // 发送文件信息
            byte[] fileName = Encoding.UTF8.GetBytes(Path.GetFileName(filePath));
            stream.Write(fileName, 0, fileName.Length);

            // 发送文件数据
            using (FileStream fs = new FileStream(filePath, FileMode.Open)) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) {
                    stream.Write(buffer, 0, bytesRead);
                }
            }
        }
    }
}

二、UDP通信实现

1. 实时数据传输(无连接)

public class UdpRealTime {
    private const int Port = 54321;
    private static UdpClient udpServer = new UdpClient(Port);

    public static void Start() {
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        Console.WriteLine("UDP服务器已启动...");

        while (true) {
            byte[] received = udpServer.Receive(ref remoteEP);
            string message = Encoding.UTF8.GetString(received);
            Console.WriteLine($"收到来自 {remoteEP}: {message}");

            // 回显响应
            udpServer.Send(Encoding.UTF8.GetBytes("ACK"), 3, remoteEP);
        }
    }
}

// 客户端
public class UdpClientApp {
    public static void Send(string message, string serverIp) {
        using (UdpClient client = new UdpClient()) {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(serverIp), 54321);
            byte[] data = Encoding.UTF8.GetBytes(message);
            client.Send(data, data.Length, remoteEP);
            
            // 接收回显
            IPEndPoint sendEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] response = client.Receive(ref sendEP);
            Console.WriteLine($"服务器响应: {Encoding.UTF8.GetString(response)}");
        }
    }
}

三、文件传输增强方案

1. 断点续传支持

// 服务器端扩展
public class ResumableTcpServer {
    public static void ResumeTransfer(TcpClient client) {
        using (NetworkStream stream = client.GetStream()) {
            // 获取已传输字节数
            byte[] resumeInfo = new byte[8];
            stream.Read(resumeInfo, 0, 8);
            long startPosition = BitConverter.ToInt64(resumeInfo, 0);

            // 从断点处继续写入
            using (FileStream fs = new FileStream("resumed_file.dat", FileMode.Append)) {
                fs.Seek(startPosition, SeekOrigin.Begin);
                // 继续接收数据...
            }
        }
    }
}

// 客户端扩展
public class ResumableTcpClient {
    public static void SendWithResume(string filePath) {
        FileInfo fi = new FileInfo(filePath);
        long fileSize = fi.Length;
        
        // 发送文件信息(含总大小)
        using (TcpClient client = new TcpClient("127.0.0.1", 12345)) {
            NetworkStream stream = client.GetStream();
            byte[] sizeBytes = BitConverter.GetBytes(fileSize);
            stream.Write(sizeBytes, 0, sizeBytes.Length);

            // 断点续传逻辑
            using (FileStream fs = new FileStream(filePath, FileMode.Open)) {
                fs.Seek(0, SeekOrigin.Begin); // 实际应用中需读取已传输位置
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) {
                    stream.Write(buffer, 0, bytesRead);
                }
            }
        }
    }
}

四、协议对比与选型建议

特性 TCP UDP
连接方式 面向连接 无连接
可靠性 保证送达、顺序、完整性 不保证
传输效率 较低(有握手和确认机制) 高(无额外开销)
适用场景 文件传输、Web服务 实时音视频、在线游戏、DNS查询
典型实现类 TcpListener/TcpClient UdpClient

五、安全增强措施

  1. SSL/TLS加密

    using (SslStream sslStream = new SslStream(stream, false)) {
        SslStream.AuthenticateAsServer(serverCertificate);
        await sslStream.WriteAsync(encryptedData);
    }
    
  2. 数据校验

    // 添加CRC32校验
    public byte[] AddChecksum(byte[] data) {
        using (var crc32 = new CRC32()) {
            byte[] checksum = crc32.ComputeHash(data);
            return checksum.Concat(data).ToArray();
        }
    }
    

六、完整项目结构示例

SocketApp/
├── Server/
│   ├── TcpServer.cs
│   ├── UdpServer.cs
│   └── FileTransferHandler.cs
├── Client/
│   ├── TcpClient.cs
│   ├── UdpClient.cs
│   └── FileSender.cs
├── Common/
│   ├── ProtocolParser.cs
│   └── Security/
│       └── AesEncryption.cs
└── Tests/
    └── NetworkTests.cs

参考代码 socket通讯(tcp/udp/文件传输等) www.youwenfan.com/contentcnj/57550.html

七、调试与测试建议

  1. 网络模拟工具

    • 使用WireShark抓包分析协议格式
    • 通过Clumsy模拟网络延迟/丢包
  2. 单元测试示例

    [TestClass]
    public class NetworkTests {
        [TestMethod]
        public async Task TestTcpTransfer() {
            var server = new TcpServer();
            var client = new TcpClient();
            
            await server.Start();
            await client.SendFile("test.dat");
            
            Assert.IsTrue(File.Exists("received_test.dat"));
        }
    }
    
posted @ 2025-10-16 16:09  lingxingqi  阅读(17)  评论(0)    收藏  举报