C# 网络编程深度分析

C# 网络编程深度分析

目录

网络编程基础

OSI七层模型与.NET网络栈

应用层    ─── HTTP/FTP/SMTP (HttpClient, WebClient)
表示层    ─── SSL/TLS (SslStream)
会话层    ─── Socket会话管理
传输层    ─── TCP/UDP (TcpClient, UdpClient, Socket)
网络层    ─── IP (IPAddress, IPEndPoint)
数据链路层 ─── 以太网/WiFi
物理层    ─── 硬件

.NET网络编程层次结构

// 高级抽象
HttpClient → WebRequest → ServicePoint

// 中级抽象  
TcpClient/UdpClient → NetworkStream

// 底层抽象
Socket → Winsock API

Socket编程详解

Socket基础概念

Socket类型
// 流式Socket (TCP)
Socket tcpSocket = new Socket(AddressFamily.InterNetwork, 
                             SocketType.Stream, 
                             ProtocolType.Tcp);

// 数据报Socket (UDP)
Socket udpSocket = new Socket(AddressFamily.InterNetwork, 
                             SocketType.Dgram, 
                             ProtocolType.Udp);

// 原始Socket (需要管理员权限)
Socket rawSocket = new Socket(AddressFamily.InterNetwork, 
                             SocketType.Raw, 
                             ProtocolType.Icmp);
地址族与协议
public enum AddressFamily
{
    InterNetwork = 2,     // IPv4
    InterNetworkV6 = 23,  // IPv6
    Unix = 1,             // Unix域套接字
}

public enum ProtocolType
{
    Tcp = 6,              // 传输控制协议
    Udp = 17,             // 用户数据报协议
    Icmp = 1,             // 互联网控制消息协议
}

TCP Socket编程

服务端实现
public class TcpServer
{
    private Socket serverSocket;
    private readonly List<Socket> clients = new List<Socket>();
    
    public async Task StartAsync(IPEndPoint endPoint)
    {
        serverSocket = new Socket(AddressFamily.InterNetwork, 
                                 SocketType.Stream, 
                                 ProtocolType.Tcp);
        
        // 设置Socket选项
        serverSocket.SetSocketOption(SocketOptionLevel.Socket, 
                                   SocketOptionName.ReuseAddress, true);
        serverSocket.SetSocketOption(SocketOptionLevel.Socket, 
                                   SocketOptionName.KeepAlive, true);
        
        serverSocket.Bind(endPoint);
        serverSocket.Listen(100); // 挂起连接队列的最大长度
        
        Console.WriteLine($"服务器启动在 {endPoint}");
        
        // 异步接受连接
        _ = Task.Run(AcceptClientsAsync);
    }
    
    private async Task AcceptClientsAsync()
    {
        while (true)
        {
            try
            {
                var clientSocket = await AcceptAsync();
                lock (clients)
                {
                    clients.Add(clientSocket);
                }
                
                // 为每个客户端启动处理任务
                _ = Task.Run(() => HandleClientAsync(clientSocket));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"接受连接错误: {ex.Message}");
            }
        }
    }
    
    private Task<Socket> AcceptAsync()
    {
        return Task.Factory.FromAsync(
            serverSocket.BeginAccept,
            serverSocket.EndAccept,
            null);
    }
    
    private async Task HandleClientAsync(Socket client)
    {
        var buffer = new byte[4096];
        try
        {
            while (client.Connected)
            {
                int received = await ReceiveAsync(client, buffer);
                if (received == 0) break; // 客户端断开连接
                
                // 处理接收到的数据
                var message = Encoding.UTF8.GetString(buffer, 0, received);
                Console.WriteLine($"收到消息: {message}");
                
                // 回显消息
                await SendAsync(client, buffer, received);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理客户端错误: {ex.Message}");
        }
        finally
        {
            lock (clients)
            {
                clients.Remove(client);
            }
            client.Close();
        }
    }
    
    private Task<int> ReceiveAsync(Socket socket, byte[] buffer)
    {
        return Task.Factory.FromAsync<int>(
            (callback, state) => socket.BeginReceive(buffer, 0, buffer.Length, 
                                                   SocketFlags.None, callback, state),
            socket.EndReceive,
            null);
    }
    
    private Task<int> SendAsync(Socket socket, byte[] buffer, int count)
    {
        return Task.Factory.FromAsync<int>(
            (callback, state) => socket.BeginSend(buffer, 0, count, 
                                                SocketFlags.None, callback, state),
            socket.EndSend,
            null);
    }
}
客户端实现
public class TcpClient
{
    private Socket clientSocket;
    
    public async Task ConnectAsync(IPEndPoint serverEndPoint)
    {
        clientSocket = new Socket(AddressFamily.InterNetwork, 
                                 SocketType.Stream, 
                                 ProtocolType.Tcp);
        
        // 设置连接超时
        clientSocket.ReceiveTimeout = 30000;
        clientSocket.SendTimeout = 30000;
        
        await ConnectAsync(serverEndPoint);
        Console.WriteLine($"连接到服务器 {serverEndPoint}");
        
        // 启动接收任务
        _ = Task.Run(ReceiveMessagesAsync);
    }
    
    private Task ConnectAsync(IPEndPoint endPoint)
    {
        return Task.Factory.FromAsync(
            (callback, state) => clientSocket.BeginConnect(endPoint, callback, state),
            clientSocket.EndConnect,
            null);
    }
    
    public async Task SendMessageAsync(string message)
    {
        var buffer = Encoding.UTF8.GetBytes(message);
        await SendAsync(buffer);
    }
    
    private Task SendAsync(byte[] buffer)
    {
        return Task.Factory.FromAsync<int>(
            (callback, state) => clientSocket.BeginSend(buffer, 0, buffer.Length, 
                                                      SocketFlags.None, callback, state),
            clientSocket.EndSend,
            null);
    }
    
    private async Task ReceiveMessagesAsync()
    {
        var buffer = new byte[4096];
        try
        {
            while (clientSocket.Connected)
            {
                int received = await ReceiveAsync(buffer);
                if (received == 0) break;
                
                var message = Encoding.UTF8.GetString(buffer, 0, received);
                Console.WriteLine($"收到服务器消息: {message}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"接收消息错误: {ex.Message}");
        }
    }
    
    private Task<int> ReceiveAsync(byte[] buffer)
    {
        return Task.Factory.FromAsync<int>(
            (callback, state) => clientSocket.BeginReceive(buffer, 0, buffer.Length, 
                                                         SocketFlags.None, callback, state),
            clientSocket.EndReceive,
            null);
    }
}

UDP Socket编程

UDP服务端
public class UdpServer
{
    private Socket udpSocket;
    private readonly ConcurrentDictionary<EndPoint, DateTime> clients = 
        new ConcurrentDictionary<EndPoint, DateTime>();
    
    public async Task StartAsync(IPEndPoint endPoint)
    {
        udpSocket = new Socket(AddressFamily.InterNetwork, 
                              SocketType.Dgram, 
                              ProtocolType.Udp);
        
        // UDP Socket选项
        udpSocket.SetSocketOption(SocketOptionLevel.Socket, 
                                 SocketOptionName.ReuseAddress, true);
        udpSocket.ReceiveBufferSize = 65536;
        udpSocket.SendBufferSize = 65536;
        
        // Windows平台防止ICMP端口不可达导致异常
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            const uint IOC_IN = 0x80000000;
            const uint IOC_VENDOR = 0x18000000;
            uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
            udpSocket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { 0 }, null);
        }
        
        udpSocket.Bind(endPoint);
        Console.WriteLine($"UDP服务器启动在 {endPoint}");
        
        // 开始接收数据
        _ = Task.Run(ReceiveMessagesAsync);
        
        // 定期清理超时客户端
        _ = Task.Run(CleanupClientsAsync);
    }
    
    private async Task ReceiveMessagesAsync()
    {
        var buffer = new byte[65536];
        EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
        
        while (true)
        {
            try
            {
                var result = await ReceiveFromAsync(buffer, remoteEndPoint);
                var receivedBytes = result.ReceivedBytes;
                var sender = result.RemoteEndPoint;
                
                // 更新客户端最后活跃时间
                clients[sender] = DateTime.Now;
                
                // 处理消息
                var message = Encoding.UTF8.GetString(buffer, 0, receivedBytes);
                Console.WriteLine($"收到来自 {sender} 的消息: {message}");
                
                // 回复消息
                var response = $"Echo: {message}";
                await SendToAsync(Encoding.UTF8.GetBytes(response), sender);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"接收UDP消息错误: {ex.Message}");
            }
        }
    }
    
    private Task<UdpReceiveResult> ReceiveFromAsync(byte[] buffer, EndPoint remoteEndPoint)
    {
        var tcs = new TaskCompletionSource<UdpReceiveResult>();
        
        udpSocket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, 
            ref remoteEndPoint, ar =>
            {
                try
                {
                    EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
                    int receivedBytes = udpSocket.EndReceiveFrom(ar, ref endPoint);
                    tcs.SetResult(new UdpReceiveResult 
                    { 
                        ReceivedBytes = receivedBytes, 
                        RemoteEndPoint = endPoint 
                    });
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }, null);
            
        return tcs.Task;
    }
    
    private Task SendToAsync(byte[] buffer, EndPoint remoteEndPoint)
    {
        return Task.Factory.FromAsync<int>(
            (callback, state) => udpSocket.BeginSendTo(buffer, 0, buffer.Length, 
                                                     SocketFlags.None, remoteEndPoint, 
                                                     callback, state),
            udpSocket.EndSendTo,
            null);
    }
    
    private async Task CleanupClientsAsync()
    {
        while (true)
        {
            await Task.Delay(30000); // 每30秒清理一次
            
            var timeout = DateTime.Now.AddMinutes(-5); // 5分钟超时
            var expiredClients = clients.Where(kvp => kvp.Value < timeout)
                                       .Select(kvp => kvp.Key)
                                       .ToList();
            
            foreach (var client in expiredClients)
            {
                clients.TryRemove(client, out _);
                Console.WriteLine($"清理超时客户端: {client}");
            }
        }
    }
    
    public struct UdpReceiveResult
    {
        public int ReceivedBytes;
        public EndPoint RemoteEndPoint;
    }
}

TCP vs UDP 对比

特性对比表

特性TCPUDP
连接性面向连接无连接
可靠性可靠传输不可靠传输
顺序保证保证顺序不保证顺序
流量控制
拥塞控制
头部开销20字节+8字节
传输效率较低较高
适用场景文件传输、网页浏览视频直播、游戏

使用场景选择

选择TCP的场景:
  • 文件传输: 确保数据完整性
  • Web应用: HTTP/HTTPS协议
  • 邮件系统: SMTP/POP3/IMAP
  • 数据库连接: 确保事务完整性
  • 聊天应用: 消息不能丢失
选择UDP的场景:
  • 实时游戏: 低延迟优先
  • 视频直播: 偶尔丢帧可接受
  • DNS查询: 快速响应
  • 传感器数据: 最新数据更重要
  • 广播/组播: 一对多通信

异步编程模式

演进历程

// 1. 同步阻塞 (Blocking)
int result = socket.Receive(buffer);

// 2. 异步回调 (APM - Asynchronous Programming Model)
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, 
    callback, state);

// 3. 事件异步模式 (EAP - Event-based Asynchronous Pattern)
var args = new SocketAsyncEventArgs();
args.SetBuffer(buffer, 0, buffer.Length);
args.Completed += OnReceiveCompleted;
socket.ReceiveAsync(args);

// 4. 任务异步模式 (TAP - Task-based Asynchronous Pattern)
int result = await socket.ReceiveAsync(buffer, SocketFlags.None);

现代异步模式详解

SocketAsyncEventArgs 模式
public class HighPerformanceServer
{
    private Socket listenSocket;
    private readonly ObjectPool<SocketAsyncEventArgs> receiveArgsPool;
    private readonly ObjectPool<SocketAsyncEventArgs> sendArgsPool;
    private readonly SemaphoreSlim maxConnectionsSemaphore;
    
    public HighPerformanceServer(int maxConnections)
    {
        maxConnectionsSemaphore = new SemaphoreSlim(maxConnections, maxConnections);
        
        // 创建对象池以减少GC压力
        receiveArgsPool = new ObjectPool<SocketAsyncEventArgs>(
            () => CreateReceiveEventArgs(), 
            maxConnections);
        sendArgsPool = new ObjectPool<SocketAsyncEventArgs>(
            () => CreateSendEventArgs(), 
            maxConnections);
    }
    
    private SocketAsyncEventArgs CreateReceiveEventArgs()
    {
        var args = new SocketAsyncEventArgs();
        args.SetBuffer(new byte[4096], 0, 4096);
        args.Completed += OnReceiveCompleted;
        return args;
    }
    
    private SocketAsyncEventArgs CreateSendEventArgs()
    {
        var args = new SocketAsyncEventArgs();
        args.Completed += OnSendCompleted;
        return args;
    }
    
    public async Task StartAsync(IPEndPoint endPoint)
    {
        listenSocket = new Socket(AddressFamily.InterNetwork, 
                                 SocketType.Stream, 
                                 ProtocolType.Tcp);
        listenSocket.Bind(endPoint);
        listenSocket.Listen(100);
        
        // 开始接受连接
        StartAccept(null);
    }
    
    private void StartAccept(SocketAsyncEventArgs acceptArgs)
    {
        if (acceptArgs == null)
        {
            acceptArgs = new SocketAsyncEventArgs();
            acceptArgs.Completed += OnAcceptCompleted;
        }
        else
        {
            acceptArgs.AcceptSocket = null; // 重置socket
        }
        
        // 限制并发连接数
        maxConnectionsSemaphore.Wait();
        
        bool willRaiseEvent = listenSocket.AcceptAsync(acceptArgs);
        if (!willRaiseEvent)
        {
            ProcessAccept(acceptArgs);
        }
    }
    
    private void OnAcceptCompleted(object sender, SocketAsyncEventArgs e)
    {
        ProcessAccept(e);
    }
    
    private void ProcessAccept(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // 为新连接启动接收
            var receiveArgs = receiveArgsPool.Get();
            receiveArgs.UserToken = e.AcceptSocket;
            
            StartReceive(receiveArgs);
        }
        
        // 继续接受新连接
        StartAccept(e);
    }
    
    private void StartReceive(SocketAsyncEventArgs receiveArgs)
    {
        var socket = (Socket)receiveArgs.UserToken;
        
        bool willRaiseEvent = socket.ReceiveAsync(receiveArgs);
        if (!willRaiseEvent)
        {
            ProcessReceive(receiveArgs);
        }
    }
    
    private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
    {
        ProcessReceive(e);
    }
    
    private void ProcessReceive(SocketAsyncEventArgs e)
    {
        var socket = (Socket)e.UserToken;
        
        if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
        {
            // 处理接收到的数据
            ProcessReceivedData(e);
            
            // 继续接收
            StartReceive(e);
        }
        else
        {
            // 连接关闭或出错
            CloseClientSocket(e);
        }
    }
    
    private void ProcessReceivedData(SocketAsyncEventArgs e)
    {
        // 简单回显
        var sendArgs = sendArgsPool.Get();
        sendArgs.UserToken = e.UserToken;
        sendArgs.SetBuffer(e.Buffer, e.Offset, e.BytesTransferred);
        
        var socket = (Socket)e.UserToken;
        bool willRaiseEvent = socket.SendAsync(sendArgs);
        if (!willRaiseEvent)
        {
            ProcessSend(sendArgs);
        }
    }
    
    private void OnSendCompleted(object sender, SocketAsyncEventArgs e)
    {
        ProcessSend(e);
    }
    
    private void ProcessSend(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // 发送成功,回收发送参数
            sendArgsPool.Return(e);
        }
        else
        {
            CloseClientSocket(e);
        }
    }
    
    private void CloseClientSocket(SocketAsyncEventArgs e)
    {
        var socket = (Socket)e.UserToken;
        try
        {
            socket.Shutdown(SocketShutdown.Send);
            socket.Close();
        }
        catch (Exception) { }
        
        // 回收资源
        receiveArgsPool.Return(e);
        maxConnectionsSemaphore.Release();
    }
}
现代 async/await 模式
public class ModernAsyncServer
{
    private TcpListener listener;
    private readonly CancellationTokenSource cancellationTokenSource = new();
    
    public async Task StartAsync(IPEndPoint endPoint)
    {
        listener = new TcpListener(endPoint);
        listener.Start();
        
        Console.WriteLine($"服务器启动在 {endPoint}");
        
        // 使用现代异步模式
        await AcceptClientsAsync(cancellationTokenSource.Token);
    }
    
    private async Task AcceptClientsAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                var tcpClient = await listener.AcceptTcpClientAsync();
                
                // 为每个客户端启动独立的处理任务
                _ = HandleClientAsync(tcpClient, cancellationToken);
            }
            catch (ObjectDisposedException)
            {
                break; // 服务器已停止
            }
            catch (Exception ex)
            {
                Console.WriteLine($"接受连接错误: {ex.Message}");
            }
        }
    }
    
    private async Task HandleClientAsync(TcpClient client, CancellationToken cancellationToken)
    {
        using (client)
        using (var stream = client.GetStream())
        {
            var buffer = new byte[4096];
            
            try
            {
                while (!cancellationToken.IsCancellationRequested && client.Connected)
                {
                    int bytesRead = await stream.ReadAsync(buffer, cancellationToken);
                    if (bytesRead == 0) break; // 客户端断开连接
                    
                    // 处理数据
                    var message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    Console.WriteLine($"收到消息: {message}");
                    
                    // 回复
                    var response = $"Echo: {message}";
                    var responseBytes = Encoding.UTF8.GetBytes(response);
                    await stream.WriteAsync(responseBytes, cancellationToken);
                }
            }
            catch (Exception ex) when (!(ex is OperationCanceledException))
            {
                Console.WriteLine($"处理客户端错误: {ex.Message}");
            }
        }
    }
    
    public void Stop()
    {
        cancellationTokenSource.Cancel();
        listener?.Stop();
    }
}

网络性能优化

1. 缓冲区优化

Socket缓冲区设置
public static void OptimizeSocketBuffers(Socket socket)
{
    // 设置发送缓冲区大小
    socket.SendBufferSize = 65536; // 64KB
    socket.ReceiveBufferSize = 65536; // 64KB
    
    // 禁用Nagle算法(适用于小包频繁发送)
    socket.SetSocketOption(SocketOptionLevel.Tcp, 
                          SocketOptionName.NoDelay, true);
    
    // 启用保活机制
    socket.SetSocketOption(SocketOptionLevel.Socket, 
                          SocketOptionName.KeepAlive, true);
    
    // Windows平台特定优化
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        // 设置保活参数
        byte[] keepAlive = new byte[12];
        BitConverter.GetBytes(1).CopyTo(keepAlive, 0); // 启用
        BitConverter.GetBytes(30000).CopyTo(keepAlive, 4); // 30秒开始探测
        BitConverter.GetBytes(1000).CopyTo(keepAlive, 8); // 1秒探测间隔
        
        socket.IOControl(IOControlCode.KeepAliveValues, keepAlive, null);
    }
}
内存池使用
public class BufferManager
{
    private readonly ArrayPool<byte> arrayPool;
    private readonly int bufferSize;
    
    public BufferManager(int bufferSize = 4096)
    {
        this.bufferSize = bufferSize;
        this.arrayPool = ArrayPool<byte>.Shared;
    }
    
    public byte[] RentBuffer()
    {
        return arrayPool.Rent(bufferSize);
    }
    
    public void ReturnBuffer(byte[] buffer)
    {
        arrayPool.Return(buffer, clearArray: true);
    }
}

// 使用示例
public async Task<string> ReceiveMessageAsync(NetworkStream stream)
{
    var bufferManager = new BufferManager();
    var buffer = bufferManager.RentBuffer();
    
    try
    {
        int bytesRead = await stream.ReadAsync(buffer);
        return Encoding.UTF8.GetString(buffer, 0, bytesRead);
    }
    finally
    {
        bufferManager.ReturnBuffer(buffer);
    }
}

2. 连接池管理

public class ConnectionPool<T> : IDisposable where T : class
{
    private readonly ConcurrentQueue<T> connections = new();
    private readonly Func<Task<T>> connectionFactory;
    private readonly Action<T> connectionReset;
    private readonly int maxSize;
    private volatile int currentCount;
    
    public ConnectionPool(
        Func<Task<T>> connectionFactory,
        Action<T> connectionReset = null,
        int maxSize = 100)
    {
        this.connectionFactory = connectionFactory;
        this.connectionReset = connectionReset;
        this.maxSize = maxSize;
    }
    
    public async Task<T> GetConnectionAsync()
    {
        if (connections.TryDequeue(out T connection))
        {
            connectionReset?.Invoke(connection);
            return connection;
        }
        
        return await connectionFactory();
    }
    
    public void ReturnConnection(T connection)
    {
        if (connection == null) return;
        
        if (currentCount < maxSize)
        {
            connections.Enqueue(connection);
            Interlocked.Increment(ref currentCount);
        }
        else
        {
            // 连接池已满,释放连接
            if (connection is IDisposable disposable)
            {
                disposable.Dispose();
            }
        }
    }
    
    public void Dispose()
    {
        while (connections.TryDequeue(out T connection))
        {
            if (connection is IDisposable disposable)
            {
                disposable.Dispose();
            }
        }
    }
}

// 使用示例
public class HttpClientPool
{
    private readonly ConnectionPool<HttpClient> pool;
    
    public HttpClientPool()
    {
        pool = new ConnectionPool<HttpClient>(
            connectionFactory: () => Task.FromResult(new HttpClient()),
            connectionReset: client => { /* 重置状态 */ },
            maxSize: 50
        );
    }
    
    public async Task<string> GetAsync(string url)
    {
        var client = await pool.GetConnectionAsync();
        try
        {
            return await client.GetStringAsync(url);
        }
        finally
        {
            pool.ReturnConnection(client);
        }
    }
}

3. 批量处理优化

public class BatchProcessor<T>
{
    private readonly List<T> batch = new();
    private readonly int batchSize;
    private readonly TimeSpan flushInterval;
    private readonly Func<IEnumerable<T>, Task> processor;
    private readonly Timer flushTimer;
    private readonly object lockObject = new();
    
    public BatchProcessor(
        int batchSize,
        TimeSpan flushInterval,
        Func<IEnumerable<T>, Task> processor)
    {
        this.batchSize = batchSize;
        this.flushInterval = flushInterval;
        this.processor = processor;
        
        flushTimer = new Timer(TimerCallback, null, flushInterval, flushInterval);
    }
    
    public async Task AddAsync(T item)
    {
        List<T> itemsToProcess = null;
        
        lock (lockObject)
        {
            batch.Add(item);
            
            if (batch.Count >= batchSize)
            {
                itemsToProcess = new List<T>(batch);
                batch.Clear();
            }
        }
        
        if (itemsToProcess != null)
        {
            await processor(itemsToProcess);
        }
    }
    
    private async void TimerCallback(object state)
    {
        List<T> itemsToProcess = null;
        
        lock (lockObject)
        {
            if (batch.Count > 0)
            {
                itemsToProcess = new List<T>(batch);
                batch.Clear();
            }
        }
        
        if (itemsToProcess != null)
        {
            await processor(itemsToProcess);
        }
    }
    
    public async Task FlushAsync()
    {
        List<T> itemsToProcess = null;
        
        lock (lockObject)
        {
            if (batch.Count > 0)
            {
                itemsToProcess = new List<T>(batch);
                batch.Clear();
            }
        }
        
        if (itemsToProcess != null)
        {
            await processor(itemsToProcess);
        }
    }
    
    public void Dispose()
    {
        flushTimer?.Dispose();
        FlushAsync().Wait();
    }
}

// 使用示例:批量发送网络消息
public class NetworkMessageSender
{
    private readonly BatchProcessor<NetworkMessage> batchProcessor;
    private readonly Socket socket;
    
    public NetworkMessageSender(Socket socket)
    {
        this.socket = socket;
        batchProcessor = new BatchProcessor<NetworkMessage>(
            batchSize: 100,
            flushInterval: TimeSpan.FromMilliseconds(10),
            processor: SendBatchAsync
        );
    }
    
    public async Task SendMessageAsync(NetworkMessage message)
    {
        await batchProcessor.AddAsync(message);
    }
    
    private async Task SendBatchAsync(IEnumerable<NetworkMessage> messages)
    {
        var messageList = messages.ToList();
        if (messageList.Count == 0) return;
        
        // 将多个消息打包发送
        var batchData = SerializeBatch(messageList);
        await SendAsync(batchData);
    }
    
    private byte[] SerializeBatch(List<NetworkMessage> messages)
    {
        using var stream = new MemoryStream();
        using var writer = new BinaryWriter(stream);
        
        writer.Write(messages.Count); // 消息数量
        foreach (var message in messages)
        {
            var data = message.Serialize();
            writer.Write(data.Length);
            writer.Write(data);
        }
        
        return stream.ToArray();
    }
    
    private async Task SendAsync(byte[] data)
    {
        await Task.Factory.FromAsync(
            (callback, state) => socket.BeginSend(data, 0, data.Length, 
                                                SocketFlags.None, callback, state),
            socket.EndSend,
            null);
    }
}

常见问题与解决方案

1. 内存泄漏问题

问题:Socket未正确释放
// ❌ 错误做法
public void BadExample()
{
    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect(new IPEndPoint(IPAddress.Loopback, 8080));
    // 忘记释放socket
}

// ✅ 正确做法
public async Task GoodExample()
{
    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    await ConnectAsync(socket, new IPEndPoint(IPAddress.Loopback, 8080));
    // socket会自动释放
}
问题:事件处理器未移除
// ❌ 错误做法
public class BadEventHandler
{
    private Socket socket;
    
    public void Subscribe()
    {
        var args = new SocketAsyncEventArgs();
        args.Completed += OnCompleted; // 可能导致内存泄漏
    }
    
    private void OnCompleted(object sender, SocketAsyncEventArgs e)
    {
        // 处理逻辑
    }
}

// ✅ 正确做法
public class GoodEventHandler : IDisposable
{
    private SocketAsyncEventArgs args;
    
    public void Subscribe()
    {
        args = new SocketAsyncEventArgs();
        args.Completed += OnCompleted;
    }
    
    private void OnCompleted(object sender, SocketAsyncEventArgs e)
    {
        // 处理逻辑
    }
    
    public void Dispose()
    {
        if (args != null)
        {
            args.Completed -= OnCompleted;
            args.Dispose();
        }
    }
}

2. 线程安全问题

问题:并发访问共享状态
// ❌ 线程不安全
public class UnsafeCounter
{
    private int count = 0;
    
    public void Increment()
    {
        count++; // 非原子操作
    }
    
    public int GetCount()
    {
        return count; // 可能读取到中间状态
    }
}

// ✅ 线程安全的解决方案
public class SafeCounter
{
    private long count = 0;
    
    public void Increment()
    {
        Interlocked.Increment(ref count);
    }
    
    public long GetCount()
    {
        return Interlocked.Read(ref count);
    }
}

// 或使用并发集合
public class ConcurrentConnectionManager
{
    private readonly ConcurrentDictionary<string, Socket> connections 
        = new ConcurrentDictionary<string, Socket>();
    
    public void AddConnection(string id, Socket socket)
    {
        connections.TryAdd(id, socket);
    }
    
    public bool RemoveConnection(string id)
    {
        return connections.TryRemove(id, out _);
    }
    
    public Socket GetConnection(string id)
    {
        connections.TryGetValue(id, out Socket socket);
        return socket;
    }
}

3. 异常处理最佳实践

public class RobustNetworkClient
{
    private readonly ILogger logger;
    private readonly RetryPolicy retryPolicy;
    
    public RobustNetworkClient(ILogger logger)
    {
        this.logger = logger;
        this.retryPolicy = new RetryPolicy(maxAttempts: 3, delay: TimeSpan.FromSeconds(1));
    }
    
    public async Task<T> SendWithRetryAsync<T>(
        Func<Task<T>> operation,
        CancellationToken cancellationToken = default)
    {
        return await retryPolicy.ExecuteAsync(async () =>
        {
            try
            {
                return await operation();
            }
            catch (SocketException ex) when (IsRetriableError(ex))
            {
                logger.LogWarning($"网络操作失败,将重试: {ex.Message}");
                throw; // 重新抛出以触发重试
            }
            catch (TimeoutException ex)
            {
                logger.LogWarning($"操作超时,将重试: {ex.Message}");
                throw;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "网络操作发生不可重试的错误");
                throw; // 不重试的错误
            }
        }, cancellationToken);
    }
    
    private static bool IsRetriableError(SocketException ex)
    {
        return ex.SocketErrorCode switch
        {
            SocketError.NetworkDown => true,
            SocketError.NetworkUnreachable => true,
            SocketError.HostDown => true,
            SocketError.HostUnreachable => true,
            SocketError.ConnectionRefused => true,
            SocketError.TimedOut => true,
            _ => false
        };
    }
}

public class RetryPolicy
{
    private readonly int maxAttempts;
    private readonly TimeSpan delay;
    
    public RetryPolicy(int maxAttempts, TimeSpan delay)
    {
        this.maxAttempts = maxAttempts;
        this.delay = delay;
    }
    
    public async Task<T> ExecuteAsync<T>(
        Func<Task<T>> operation, 
        CancellationToken cancellationToken = default)
    {
        Exception lastException = null;
        
        for (int attempt = 1; attempt <= maxAttempts; attempt++)
        {
            try
            {
                return await operation();
            }
            catch (Exception ex)
            {
                lastException = ex;
                
                if (attempt == maxAttempts)
                {
                    throw new AggregateException($"操作在{maxAttempts}次尝试后失败", ex);
                }
                
                await Task.Delay(delay * attempt, cancellationToken); // 指数退避
            }
        }
        
        throw lastException; // 理论上不会执行到这里
    }
}

4. 性能监控与诊断

public class NetworkPerformanceMonitor
{
    private readonly IMetricsCollector metricsCollector;
    private long totalBytesSent;
    private long totalBytesReceived;
    private long totalConnections;
    private long activeConnections;
    
    public NetworkPerformanceMonitor(IMetricsCollector metricsCollector)
    {
        this.metricsCollector = metricsCollector;
        
        // 定期上报指标
        _ = Task.Run(ReportMetricsAsync);
    }
    
    public void OnDataSent(int bytes)
    {
        Interlocked.Add(ref totalBytesSent, bytes);
        metricsCollector.Counter("network_bytes_sent").Increment(bytes);
    }
    
    public void OnDataReceived(int bytes)
    {
        Interlocked.Add(ref totalBytesReceived, bytes);
        metricsCollector.Counter("network_bytes_received").Increment(bytes);
    }
    
    public void OnConnectionEstablished()
    {
        Interlocked.Increment(ref totalConnections);
        Interlocked.Increment(ref activeConnections);
        metricsCollector.Gauge("active_connections").Set(activeConnections);
    }
    
    public void OnConnectionClosed()
    {
        Interlocked.Decrement(ref activeConnections);
        metricsCollector.Gauge("active_connections").Set(activeConnections);
    }
    
    private async Task ReportMetricsAsync()
    {
        while (true)
        {
            await Task.Delay(TimeSpan.FromMinutes(1));
            
            metricsCollector.Gauge("total_bytes_sent").Set(totalBytesSent);
            metricsCollector.Gauge("total_bytes_received").Set(totalBytesReceived);
            metricsCollector.Gauge("total_connections").Set(totalConnections);
        }
    }
}

// 使用示例
public class MonitoredTcpServer
{
    private readonly NetworkPerformanceMonitor monitor;
    
    public MonitoredTcpServer(NetworkPerformanceMonitor monitor)
    {
        this.monitor = monitor;
    }
    
    private async Task HandleClientAsync(Socket client)
    {
        monitor.OnConnectionEstablished();
        
        try
        {
            var buffer = new byte[4096];
            while (client.Connected)
            {
                int received = await ReceiveAsync(client, buffer);
                if (received == 0) break;
                
                monitor.OnDataReceived(received);
                
                // 处理数据并发送响应
                var response = ProcessData(buffer, received);
                await SendAsync(client, response);
                
                monitor.OnDataSent(response.Length);
            }
        }
        finally
        {
            monitor.OnConnectionClosed();
            client.Close();
        }
    }
}

最佳实践

1. 架构设计原则

分层架构
┌─────────────────────────────────────┐
│          应用层 (Application)        │
├─────────────────────────────────────┤
│          传输层 (Transport)          │
├─────────────────────────────────────┤
│          协议层 (Protocol)           │
├─────────────────────────────────────┤
│          网络层 (Network)            │
└─────────────────────────────────────┘
// 网络层接口
public interface INetworkTransport
{
    Task<bool> SendAsync(byte[] data, EndPoint endpoint);
    event Action<byte[], EndPoint> DataReceived;
}

// 协议层接口
public interface IProtocolHandler
{
    Task<bool> SendMessageAsync<T>(T message, string targetId);
    event Action<TMessage, string> MessageReceived<TMessage>;
}

// 传输层接口
public interface IMessageTransport
{
    Task<TResponse> RequestAsync<TRequest, TResponse>(TRequest request, string targetId);
    Task SendAsync<T>(T message, string targetId);
}
配置管理
public class NetworkConfiguration
{
    public int MaxConnections { get; set; } = 1000;
    public int ReceiveBufferSize { get; set; } = 65536;
    public int SendBufferSize { get; set; } = 65536;
    public TimeSpan ConnectionTimeout { get; set; } = TimeSpan.FromSeconds(30);
    public TimeSpan KeepAliveInterval { get; set; } = TimeSpan.FromSeconds(30);
    public int MaxRetryAttempts { get; set; } = 3;
    public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(1);
    public bool EnableNagleAlgorithm { get; set; } = false;
    public bool EnableCompression { get; set; } = true;
    public CompressionLevel CompressionLevel { get; set; } = CompressionLevel.Optimal;
}

public class ConfigurableNetworkServer
{
    private readonly NetworkConfiguration config;
    
    public ConfigurableNetworkServer(NetworkConfiguration config)
    {
        this.config = config ?? throw new ArgumentNullException(nameof(config));
    }
    
    public Socket CreateOptimizedSocket()
    {
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        
        // 应用配置
        socket.ReceiveBufferSize = config.ReceiveBufferSize;
        socket.SendBufferSize = config.SendBufferSize;
        socket.ReceiveTimeout = (int)config.ConnectionTimeout.TotalMilliseconds;
        socket.SendTimeout = (int)config.ConnectionTimeout.TotalMilliseconds;
        
        socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, !config.EnableNagleAlgorithm);
        socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
        
        return socket;
    }
}

2. 错误处理策略

public enum NetworkErrorSeverity
{
    Transient,    // 临时错误,可重试
    Persistent,   // 持久错误,需要重新连接
    Fatal         // 致命错误,需要停止服务
}

public class NetworkErrorHandler
{
    private readonly ILogger logger;
    private readonly IMetricsCollector metrics;
    
    public NetworkErrorHandler(ILogger logger, IMetricsCollector metrics)
    {
        this.logger = logger;
        this.metrics = metrics;
    }
    
    public NetworkErrorSeverity ClassifyError(Exception exception)
    {
        return exception switch
        {
            SocketException sockEx => ClassifySocketError(sockEx),
            TimeoutException => NetworkErrorSeverity.Transient,
            ObjectDisposedException => NetworkErrorSeverity.Fatal,
            OutOfMemoryException => NetworkErrorSeverity.Fatal,
            ArgumentException => NetworkErrorSeverity.Fatal,
            IOException ioEx => ClassifyIOError(ioEx),
            _ => NetworkErrorSeverity.Persistent
        };
    }
    
    private NetworkErrorSeverity ClassifySocketError(SocketException ex)
    {
        return ex.SocketErrorCode switch
        {
            SocketError.TimedOut => NetworkErrorSeverity.Transient,
            SocketError.NetworkDown => NetworkErrorSeverity.Transient,
            SocketError.NetworkUnreachable => NetworkErrorSeverity.Transient,
            SocketError.HostDown => NetworkErrorSeverity.Transient,
            SocketError.HostUnreachable => NetworkErrorSeverity.Transient,
            SocketError.ConnectionRefused => NetworkErrorSeverity.Persistent,
            SocketError.ConnectionReset => NetworkErrorSeverity.Persistent,
            SocketError.ConnectionAborted => NetworkErrorSeverity.Persistent,
            SocketError.AddressAlreadyInUse => NetworkErrorSeverity.Fatal,
            SocketError.AddressNotAvailable => NetworkErrorSeverity.Fatal,
            _ => NetworkErrorSeverity.Persistent
        };
    }
    
    private NetworkErrorSeverity ClassifyIOError(IOException ex)
    {
        if (ex.InnerException is SocketException sockEx)
        {
            return ClassifySocketError(sockEx);
        }
        return NetworkErrorSeverity.Persistent;
    }
    
    public async Task<bool> HandleErrorAsync(Exception exception, string context)
    {
        var severity = ClassifyError(exception);
        
        // 记录错误
        logger.LogError(exception, "网络错误发生在 {Context}, 严重程度: {Severity}", 
                       context, severity);
        
        // 更新指标
        metrics.Counter($"network_errors_{severity.ToString().ToLower()}").Increment();
        
        // 根据严重程度决定处理策略
        switch (severity)
        {
            case NetworkErrorSeverity.Transient:
                await Task.Delay(TimeSpan.FromMilliseconds(100)); // 短暂延迟
                return true; // 可以重试
                
            case NetworkErrorSeverity.Persistent:
                await Task.Delay(TimeSpan.FromSeconds(5)); // 较长延迟
                return true; // 可以重试,但需要更长延迟
                
            case NetworkErrorSeverity.Fatal:
                logger.LogCritical(exception, "致命网络错误,服务将停止");
                return false; // 不能重试
                
            default:
                return false;
        }
    }
}

3. 消息序列化与压缩

public interface IMessageSerializer
{
    byte[] Serialize<T>(T message);
    T Deserialize<T>(byte[] data);
    byte[] SerializeWithCompression<T>(T message);
    T DeserializeWithCompression<T>(byte[] compressedData);
}

public class JsonMessageSerializer : IMessageSerializer
{
    private readonly JsonSerializerSettings jsonSettings;
    
    public JsonMessageSerializer()
    {
        jsonSettings = new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto,
            NullValueHandling = NullValueHandling.Ignore,
            DateFormatHandling = DateFormatHandling.IsoDateFormat
        };
    }
    
    public byte[] Serialize<T>(T message)
    {
        var json = JsonConvert.SerializeObject(message, jsonSettings);
        return Encoding.UTF8.GetBytes(json);
    }
    
    public T Deserialize<T>(byte[] data)
    {
        var json = Encoding.UTF8.GetString(data);
        return JsonConvert.DeserializeObject<T>(json, jsonSettings);
    }
    
    public byte[] SerializeWithCompression<T>(T message)
    {
        var data = Serialize(message);
        return CompressData(data);
    }
    
    public T DeserializeWithCompression<T>(byte[] compressedData)
    {
        var data = DecompressData(compressedData);
        return Deserialize<T>(data);
    }
    
    private byte[] CompressData(byte[] data)
    {
        using var output = new MemoryStream();
        using (var gzip = new GZipStream(output, CompressionLevel.Optimal))
        {
            gzip.Write(data, 0, data.Length);
        }
        return output.ToArray();
    }
    
    private byte[] DecompressData(byte[] compressedData)
    {
        using var input = new MemoryStream(compressedData);
        using var gzip = new GZipStream(input, CompressionMode.Decompress);
        using var output = new MemoryStream();
        gzip.CopyTo(output);
        return output.ToArray();
    }
}

// 高性能二进制序列化器
public class BinaryMessageSerializer : IMessageSerializer
{
    public byte[] Serialize<T>(T message)
    {
        using var stream = new MemoryStream();
        using var writer = new BinaryWriter(stream);
        
        // 写入类型信息
        writer.Write(typeof(T).AssemblyQualifiedName);
        
        // 使用MessagePack等高性能序列化器
        var data = MessagePackSerializer.Serialize(message);
        writer.Write(data.Length);
        writer.Write(data);
        
        return stream.ToArray();
    }
    
    public T Deserialize<T>(byte[] data)
    {
        using var stream = new MemoryStream(data);
        using var reader = new BinaryReader(stream);
        
        // 读取类型信息
        var typeName = reader.ReadString();
        var type = Type.GetType(typeName);
        
        // 读取数据
        var dataLength = reader.ReadInt32();
        var messageData = reader.ReadBytes(dataLength);
        
        return MessagePackSerializer.Deserialize<T>(messageData);
    }
    
    public byte[] SerializeWithCompression<T>(T message)
    {
        var data = Serialize(message);
        return data.Length > 1024 ? CompressData(data) : data; // 只压缩大于1KB的数据
    }
    
    public T DeserializeWithCompression<T>(byte[] data)
    {
        // 简单的压缩标识检查(实际应用中应该有更完善的标识机制)
        if (IsCompressed(data))
        {
            data = DecompressData(data);
        }
        return Deserialize<T>(data);
    }
    
    private bool IsCompressed(byte[] data)
    {
        // 检查GZIP魔数
        return data.Length > 2 && data[0] == 0x1F && data[1] == 0x8B;
    }
    
    private byte[] CompressData(byte[] data)
    {
        using var output = new MemoryStream();
        using (var deflate = new DeflateStream(output, CompressionLevel.Fastest))
        {
            deflate.Write(data, 0, data.Length);
        }
        return output.ToArray();
    }
    
    private byte[] DecompressData(byte[] compressedData)
    {
        using var input = new MemoryStream(compressedData);
        using var deflate = new DeflateStream(input, CompressionMode.Decompress);
        using var output = new MemoryStream();
        deflate.CopyTo(output);
        return output.ToArray();
    }
}

4. 安全性考虑

public class SecureNetworkServer
{
    private readonly RSA serverPrivateKey;
    private readonly ConcurrentDictionary<EndPoint, SecureSession> secureSessions;
    private readonly ILogger logger;
    
    public SecureNetworkServer(ILogger logger)
    {
        this.logger = logger;
        this.serverPrivateKey = RSA.Create(2048);
        this.secureSessions = new ConcurrentDictionary<EndPoint, SecureSession>();
    }
    
    public async Task<bool> EstablishSecureSessionAsync(Socket client)
    {
        try
        {
            // 1. 发送服务器公钥
            var publicKey = serverPrivateKey.ExportRSAPublicKey();
            await SendAsync(client, publicKey);
            
            // 2. 接收客户端的对称密钥(RSA加密)
            var encryptedSymmetricKey = await ReceiveAsync(client);
            var symmetricKey = serverPrivateKey.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.OaepSHA256);
            
            // 3. 创建安全会话
            var session = new SecureSession
            {
                SymmetricKey = symmetricKey,
                EstablishedAt = DateTime.UtcNow,
                LastActivity = DateTime.UtcNow
            };
            
            secureSessions[client.RemoteEndPoint] = session;
            
            // 4. 发送确认消息
            var confirmation = EncryptData(Encoding.UTF8.GetBytes("SESSION_ESTABLISHED"), symmetricKey);
            await SendAsync(client, confirmation);
            
            logger.LogInformation("安全会话已建立: {RemoteEndPoint}", client.RemoteEndPoint);
            return true;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "建立安全会话失败: {RemoteEndPoint}", client.RemoteEndPoint);
            return false;
        }
    }
    
    public async Task<byte[]> ReceiveSecureDataAsync(Socket client)
    {
        if (!secureSessions.TryGetValue(client.RemoteEndPoint, out var session))
        {
            throw new UnauthorizedAccessException("未建立安全会话");
        }
        
        var encryptedData = await ReceiveAsync(client);
        var decryptedData = DecryptData(encryptedData, session.SymmetricKey);
        
        // 更新会话活动时间
        session.LastActivity = DateTime.UtcNow;
        
        return decryptedData;
    }
    
    public async Task SendSecureDataAsync(Socket client, byte[] data)
    {
        if (!secureSessions.TryGetValue(client.RemoteEndPoint, out var session))
        {
            throw new UnauthorizedAccessException("未建立安全会话");
        }
        
        var encryptedData = EncryptData(data, session.SymmetricKey);
        await SendAsync(client, encryptedData);
        
        // 更新会话活动时间
        session.LastActivity = DateTime.UtcNow;
    }
    
    private byte[] EncryptData(byte[] data, byte[] key)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        aes.GenerateIV();
        
        using var encryptor = aes.CreateEncryptor();
        using var output = new MemoryStream();
        
        // 写入IV
        output.Write(aes.IV, 0, aes.IV.Length);
        
        // 写入加密数据
        using (var cryptoStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
        {
            cryptoStream.Write(data, 0, data.Length);
        }
        
        return output.ToArray();
    }
    
    private byte[] DecryptData(byte[] encryptedData, byte[] key)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        
        // 提取IV
        var iv = new byte[aes.BlockSize / 8];
        Array.Copy(encryptedData, 0, iv, 0, iv.Length);
        aes.IV = iv;
        
        using var decryptor = aes.CreateDecryptor();
        using var input = new MemoryStream(encryptedData, iv.Length, encryptedData.Length - iv.Length);
        using var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read);
        using var output = new MemoryStream();
        
        cryptoStream.CopyTo(output);
        return output.ToArray();
    }
    
    // 定期清理过期会话
    private async Task CleanupExpiredSessionsAsync()
    {
        while (true)
        {
            await Task.Delay(TimeSpan.FromMinutes(5));
            
            var expiredTime = DateTime.UtcNow.AddMinutes(-30); // 30分钟超时
            var expiredSessions = secureSessions
                .Where(kvp => kvp.Value.LastActivity < expiredTime)
                .Select(kvp => kvp.Key)
                .ToList();
            
            foreach (var endpoint in expiredSessions)
            {
                if (secureSessions.TryRemove(endpoint, out _))
                {
                    logger.LogInformation("清理过期会话: {EndPoint}", endpoint);
                }
            }
        }
    }
}

public class SecureSession
{
    public byte[] SymmetricKey { get; set; }
    public DateTime EstablishedAt { get; set; }
    public DateTime LastActivity { get; set; }
}

5. 负载均衡与故障转移

public interface ILoadBalancer
{
    Task<EndPoint> GetNextEndpointAsync();
    Task ReportHealthAsync(EndPoint endpoint, bool isHealthy);
}

public class RoundRobinLoadBalancer : ILoadBalancer
{
    private readonly List<ServerEndpoint> endpoints;
    private int currentIndex = 0;
    private readonly object lockObject = new object();
    
    public RoundRobinLoadBalancer(IEnumerable<EndPoint> endpoints)
    {
        this.endpoints = endpoints.Select(ep => new ServerEndpoint 
        { 
            EndPoint = ep, 
            IsHealthy = true,
            Weight = 1
        }).ToList();
        
        // 启动健康检查
        _ = Task.Run(HealthCheckAsync);
    }
    
    public Task<EndPoint> GetNextEndpointAsync()
    {
        lock (lockObject)
        {
            var healthyEndpoints = endpoints.Where(e => e.IsHealthy).ToList();
            if (healthyEndpoints.Count == 0)
            {
                throw new InvalidOperationException("没有可用的健康端点");
            }
            
            var endpoint = healthyEndpoints[currentIndex % healthyEndpoints.Count];
            currentIndex = (currentIndex + 1) % healthyEndpoints.Count;
            
            return Task.FromResult(endpoint.EndPoint);
        }
    }

    public Task ReportHealthAsync(EndPoint endpoint, bool isHealthy)
    {
        var serverEndpoint = endpoints.FirstOrDefault(e => e.EndPoint.Equals(endpoint));
        if (serverEndpoint != null)
        {
            lock (lockObject)
            {
                serverEndpoint.IsHealthy = isHealthy;
                serverEndpoint.LastHealthCheck = DateTime.UtcNow;
            }
        }
        
        return Task.CompletedTask;
    }
    
    private async Task HealthCheckAsync()
    {
        while (true)
        {
            foreach (var endpoint in endpoints)
            {
                try
                {
                    var isHealthy = await PingEndpointAsync(endpoint.EndPoint);
                    await ReportHealthAsync(endpoint.EndPoint, isHealthy);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"健康检查失败 {endpoint.EndPoint}: {ex.Message}");
                    await ReportHealthAsync(endpoint.EndPoint, false);
                }
            }
            
            await Task.Delay(TimeSpan.FromSeconds(30)); // 每30秒检查一次
        }
    }
    
    private async Task<bool> PingEndpointAsync(EndPoint endpoint)
    {
        try
        {
            using var client = new TcpClient();
            var connectTask = client.ConnectAsync(((IPEndPoint)endpoint).Address, 
                                                 ((IPEndPoint)endpoint).Port);
            
            // 5秒超时
            if (await Task.WhenAny(connectTask, Task.Delay(5000)) == connectTask)
            {
                return client.Connected;
            }
            
            return false;
        }
        catch
        {
            return false;
        }
    }
}

public class ServerEndpoint
{
    public EndPoint EndPoint { get; set; }
    public bool IsHealthy { get; set; }
    public int Weight { get; set; }
    public DateTime LastHealthCheck { get; set; }
    public int CurrentConnections { get; set; }
}

// 加权轮询负载均衡器
public class WeightedRoundRobinLoadBalancer : ILoadBalancer
{
    private readonly List<WeightedEndpoint> endpoints;
    private readonly object lockObject = new object();
    
    public WeightedRoundRobinLoadBalancer(IEnumerable<(EndPoint endpoint, int weight)> endpoints)
    {
        this.endpoints = endpoints.Select(e => new WeightedEndpoint
        {
            EndPoint = e.endpoint,
            Weight = e.weight,
            CurrentWeight = 0,
            IsHealthy = true
        }).ToList();
    }
    
    public Task<EndPoint> GetNextEndpointAsync()
    {
        lock (lockObject)
        {
            var healthyEndpoints = endpoints.Where(e => e.IsHealthy).ToList();
            if (healthyEndpoints.Count == 0)
            {
                throw new InvalidOperationException("没有可用的健康端点");
            }
            
            // 加权轮询算法
            var totalWeight = healthyEndpoints.Sum(e => e.Weight);
            foreach (var endpoint in healthyEndpoints)
            {
                endpoint.CurrentWeight += endpoint.Weight;
            }
            
            var selected = healthyEndpoints.OrderByDescending(e => e.CurrentWeight).First();
            selected.CurrentWeight -= totalWeight;
            
            return Task.FromResult(selected.EndPoint);
        }
    }
    
    public Task ReportHealthAsync(EndPoint endpoint, bool isHealthy)
    {
        var weightedEndpoint = endpoints.FirstOrDefault(e => e.EndPoint.Equals(endpoint));
        if (weightedEndpoint != null)
        {
            lock (lockObject)
            {
                weightedEndpoint.IsHealthy = isHealthy;
            }
        }
        
        return Task.CompletedTask;
    }
}

public class WeightedEndpoint
{
    public EndPoint EndPoint { get; set; }
    public int Weight { get; set; }
    public int CurrentWeight { get; set; }
    public bool IsHealthy { get; set; }
}

// 故障转移客户端
public class FailoverNetworkClient
{
    private readonly ILoadBalancer loadBalancer;
    private readonly ILogger logger;
    private readonly ConnectionPool<Socket> connectionPool;
    private readonly SemaphoreSlim connectionSemaphore;
    
    public FailoverNetworkClient(
        ILoadBalancer loadBalancer, 
        ILogger logger,
        int maxConnections = 100)
    {
        this.loadBalancer = loadBalancer;
        this.logger = logger;
        this.connectionSemaphore = new SemaphoreSlim(maxConnections, maxConnections);
        this.connectionPool = new ConnectionPool<Socket>(
            CreateConnectionAsync,
            ResetConnection,
            maxConnections
        );
    }
    
    public async Task<TResponse> SendRequestAsync<TRequest, TResponse>(
        TRequest request,
        TimeSpan timeout = default)
    {
        if (timeout == default)
            timeout = TimeSpan.FromSeconds(30);
        
        var attempts = 0;
        const int maxAttempts = 3;
        
        while (attempts < maxAttempts)
        {
            Socket connection = null;
            EndPoint endpoint = null;
            
            try
            {
                // 获取健康的端点
                endpoint = await loadBalancer.GetNextEndpointAsync();
                
                // 获取连接
                await connectionSemaphore.WaitAsync(timeout);
                connection = await connectionPool.GetConnectionAsync();
                
                // 发送请求
                var response = await SendRequestInternalAsync<TRequest, TResponse>(
                    connection, request, timeout);
                
                // 标记端点为健康
                await loadBalancer.ReportHealthAsync(endpoint, true);
                
                return response;
            }
            catch (Exception ex)
            {
                attempts++;
                logger.LogWarning(ex, 
                    "请求失败 (尝试 {Attempt}/{MaxAttempts}) 到端点 {Endpoint}: {Message}",
                    attempts, maxAttempts, endpoint, ex.Message);
                
                // 标记端点为不健康
                if (endpoint != null)
                {
                    await loadBalancer.ReportHealthAsync(endpoint, false);
                }
                
                // 关闭有问题的连接
                if (connection != null)
                {
                    try
                    {
                        connection.Close();
                    }
                    catch { }
                }
                
                if (attempts >= maxAttempts)
                {
                    throw new AggregateException(
                        $"在{maxAttempts}次尝试后请求仍然失败", ex);
                }
                
                // 指数退避
                await Task.Delay(TimeSpan.FromMilliseconds(Math.Pow(2, attempts) * 100));
            }
            finally
            {
                if (connection != null)
                {
                    connectionPool.ReturnConnection(connection);
                }
                connectionSemaphore.Release();
            }
        }
        
        throw new InvalidOperationException("无法完成请求");
    }
    
    private async Task<Socket> CreateConnectionAsync()
    {
        var endpoint = await loadBalancer.GetNextEndpointAsync();
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        
        // 设置超时
        socket.ReceiveTimeout = 30000;
        socket.SendTimeout = 30000;
        
        await ConnectAsync(socket, endpoint);
        return socket;
    }
    
    private void ResetConnection(Socket socket)
    {
        // 检查连接是否仍然有效
        if (!socket.Connected)
        {
            socket.Close();
            throw new InvalidOperationException("连接已断开");
        }
    }
    
    private async Task<TResponse> SendRequestInternalAsync<TRequest, TResponse>(
        Socket socket, 
        TRequest request, 
        TimeSpan timeout)
    {
        // 序列化请求
        var requestData = SerializeRequest(request);
        
        // 发送请求
        await SendAsync(socket, requestData);
        
        // 接收响应
        var responseData = await ReceiveAsync(socket, timeout);
        
        // 反序列化响应
        return DeserializeResponse<TResponse>(responseData);
    }
    
    private byte[] SerializeRequest<T>(T request)
    {
        // 使用你选择的序列化器
        return JsonConvert.SerializeObject(request, Encoding.UTF8);
    }
    
    private T DeserializeResponse<T>(byte[] data)
    {
        var json = Encoding.UTF8.GetString(data);
        return JsonConvert.DeserializeObject<T>(json);
    }
    
    private async Task ConnectAsync(Socket socket, EndPoint endpoint)
    {
        await Task.Factory.FromAsync(
            (callback, state) => socket.BeginConnect(endpoint, callback, state),
            socket.EndConnect,
            null);
    }
    
    private async Task SendAsync(Socket socket, byte[] data)
    {
        await Task.Factory.FromAsync<int>(
            (callback, state) => socket.BeginSend(data, 0, data.Length, 
                                                SocketFlags.None, callback, state),
            socket.EndSend,
            null);
    }
    
    private async Task<byte[]> ReceiveAsync(Socket socket, TimeSpan timeout)
    {
        using var cts = new CancellationTokenSource(timeout);
        var buffer = new byte[4096];
        
        var received = await Task.Factory.FromAsync<int>(
            (callback, state) => socket.BeginReceive(buffer, 0, buffer.Length, 
                                                   SocketFlags.None, callback, state),
            socket.EndReceive,
            null);
        
        var result = new byte[received];
        Array.Copy(buffer, result, received);
        return result;
    }
}

总结

关键要点

  1. 选择合适的协议:根据应用需求选择TCP或UDP
  2. 异步编程:使用现代async/await模式,避免阻塞线程
  3. 资源管理:正确释放Socket和相关资源,使用对象池减少GC压力
  4. 错误处理:实现健壮的错误处理和重试机制
  5. 性能优化:合理设置缓冲区大小,使用批处理和连接池
  6. 安全性:实现加密和身份验证机制
  7. 监控:添加性能监控和健康检查
  8. 可扩展性:设计支持负载均衡和故障转移的架构

技术栈推荐

  • 高性能场景:Socket + SocketAsyncEventArgs
  • 一般应用:TcpClient/UdpClient + async/await
  • Web应用:HttpClient + HttpClientFactory
  • 实时通信:SignalR 或自定义UDP协议
  • 微服务:gRPC 或 RESTful API

性能基准

场景推荐方案典型性能
高并发服务器Socket + EventArgs10K+ 连接
文件传输TCP + 大缓冲区95%+ 带宽利用率
实时游戏UDP + 自定义协议<50ms 延迟
Web APIASP.NET Core100K+ RPS
消息队列TCP + 二进制协议1M+ 消息/秒

这份文档涵盖了C#网络编程的核心概念、最佳实践和实际应用场景,可以作为开发高性能网络应用的参考指南。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

will_csdn_go

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值