文章目录
一、TCP与UDP协议特点
1、TCP协议特点
| 特点 | 说明 | 
|---|---|
| 面向连接 | 通信前需通过三次握手建立连接,确保双方准备就绪 | 
| 可靠性 | 通过序列号、确认应答、超时重传等机制保证数据完整有序到达 | 
| 流量控制 | 自动调整传输速率避免网络拥塞 | 
| 适用场景 | 卡牌类、棋牌类、回合制等对数据完整性要求高的游戏 | 
2、UDP协议特点
| 特点 | 说明 | 
|---|---|
| 无连接 | 通信前需通过三次握手建立连接,确保双方准备就绪 | 
| 高效性 | 通过序列号、确认应答、超时重传等机制保证数据完整有序到达 | 
| 不可靠 | 自动调整传输速率避免网络拥塞 | 
| 适用场景 | 实时性要求高的游戏如FPS、MOBA等 | 
3、协议对比
| 特性 | TCP | UDP | 
|---|---|---|
| 连接方式 | 面向连接 | 无连接 | 
| 可靠性 | 高 | 低 | 
| 传输速度 | 较慢 | 快 | 
| 数据顺序 | 保证 | 不保证 | 
| 流量控制 | 有 | 无 | 
| 头部大小 | 20字节 | 8字节 | 
| 使用场景 | 数据完整性优先 | 实时性优先 | 
二、TCP与UDP协议实现
1、TCP通信实现
1、TCP服务端实现
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
using System.Text;
class TCPServer
{
    static void Main()
    {
        // 1. 创建TCP Socket
        Socket tcpServer = new Socket(AddressFamily.InterNetwork, 
                                    SocketType.Stream, 
                                    ProtocolType.Tcp);
        
        // 2. 绑定IP和端口
        IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
        tcpServer.Bind(endpoint);
        
        // 3. 开始监听
        tcpServer.Listen(10);
        Console.WriteLine("服务器启动完成");
        
        // 4. 接受客户端连接
        Socket clientSocket = tcpServer.Accept();
        Console.WriteLine("客户端已连接");
        
        // 5. 接收数据
        byte[] data = new byte[1024];
        int length = clientSocket.Receive(data);
        string message = Encoding.UTF8.GetString(data, 0, length);
        Console.WriteLine("收到消息: " + message);
        
        // 6. 发送数据
        clientSocket.Send(Encoding.UTF8.GetBytes("服务器已收到"));
        
        // 7. 关闭连接
        clientSocket.Close();
        tcpServer.Close();
    }
}
        2、TCP客户端实现
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
using System.Text;
class TCPClient
{
    static void Main()
    {
        // 1. 创建TCP Socket
        //SocketType.Stream 对应面向连接的TCP协议
        Socket tcpClient = new Socket(AddressFamily.InterNetwork, 
                                    SocketType.Stream, 
                                    ProtocolType.Tcp);
        
        // 2. 连接服务器
        tcpClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888));
        
        // 3. 发送数据
        tcpClient.Send(Encoding.UTF8.GetBytes("Hello Server"));
        
        // 4. 接收响应
        byte[] data = new byte[1024];
        int length = tcpClient.Receive(data);
        Console.WriteLine("服务器响应: " + Encoding.UTF8.GetString(data, 0, length));
        
        // 5. 关闭连接
        tcpClient.Close();
    }
}
        2、UDP通信实现
1、UDP服务端实现
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
using System.Text;
class UDPServer
{
    static void Main()
    {
        // 1. 创建UDP Socket
        // SocketType.Dgram 对应无连接的UDP协议
        Socket udpServer = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Dgram,
                                    ProtocolType.Udp);
        
        // 2. 绑定端口
        udpServer.Bind(new IPEndPoint(IPAddress.Any, 8889));
        Console.WriteLine("UDP服务器已启动");
        
        // 3. 接收数据
        //UDP接收响应必须有端口号,但可通过设为0由系统自动分配
        EndPoint clientEnd = new IPEndPoint(IPAddress.Any, 0);
        byte[] data = new byte[1024];
        int length = udpServer.ReceiveFrom(data, ref clientEnd);
        string message = Encoding.UTF8.GetString(data, 0, length);
        Console.WriteLine($"收到来自{clientEnd}的消息: {message}");
        
        // 4. 发送响应
        udpServer.SendTo(Encoding.UTF8.GetBytes("UDP服务器已收到"), clientEnd);
        
        // 5. 关闭Socket
        udpServer.Close();
    }
}
        2、UDP客户端实现
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
using System.Text;
class UDPClient
{
    static void Main()
    {
        // 1. 创建UDP Socket
        Socket udpClient = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Dgram,
                                    ProtocolType.Udp);
        
        // 2. 发送数据
        IPEndPoint serverEnd = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8889);
        udpClient.SendTo(Encoding.UTF8.GetBytes("Hello UDP Server"), serverEnd);
        
        // 3. 接收响应
        //UDP接收响应必须有端口号,但可通过设为0由系统自动分配
        byte[] data = new byte[1024];
        EndPoint remoteEnd = new IPEndPoint(IPAddress.Any, 0);
        int length = udpClient.ReceiveFrom(data, ref remoteEnd);
        Console.WriteLine($"收到来自{remoteEnd}的响应: {Encoding.UTF8.GetString(data, 0, length)}");
        
        // 4. 关闭Socket
        udpClient.Close();
    }
}
        3、实现对比
| 特性 | TCP实现 | UDP实现 | 
|---|---|---|
| Scoket创建 | SocketType.Stream,ProtocolType.Tcp | SocketType.Dgram,ProtocolType.Udp | 
| 连接管理 | 需要Connect()/Accept()建立连接 | 无连接,直接发送数据 | 
| 数据传输 | Send()/Receive() | SendTo()/ReceiveFrom() | 
| 错误处理 | 处理连接中断,超时重传等 | 主要处理端口不可达等 | 
三、TCPListener与UdpClient
1、TCPListener使用
TCPListener是对Socket的高级封装,简化了TCP服务端的创建过程:
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
class TCPListenerExample
{
    static void Main()
    {
        // 1. 创建TCPListener
        TcpListener listener = new TcpListener(IPAddress.Any, 8888);
        listener.Start();
        Console.WriteLine("TCPListener已启动");
        
        // 2. 接受客户端连接
        TcpClient client = listener.AcceptTcpClient();
        Console.WriteLine("客户端已连接");
        
        // 3. 获取网络流
        NetworkStream stream = client.GetStream();
        
        // 4. 读取数据
        byte[] buffer = new byte[1024];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine("收到消息: " + message);
        
        // 5. 发送响应
        byte[] response = Encoding.UTF8.GetBytes("TCPListener已收到");
        stream.Write(response, 0, response.Length);
        
        // 6. 关闭连接
        client.Close();
        listener.Stop();
    }
}
        2、UDPListener使用
UdpClient是对UDP Socket的高级封装,简化了UDP通信过程:
            
            
              csharp
              
              
            
          
          using System.Net;
using System.Net.Sockets;
class UdpClientExample
{
    static void Main()
    {
        // 1. 创建UdpClient
        UdpClient udpClient = new UdpClient(8888);
        Console.WriteLine("UdpClient已启动");
        
        // 2. 接收数据
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        byte[] receivedData = udpClient.Receive(ref remoteEP);
        string message = Encoding.UTF8.GetString(receivedData);
        Console.WriteLine($"收到来自{remoteEP}的消息: {message}");
        
        // 3. 发送响应
        byte[] response = Encoding.UTF8.GetBytes("UdpClient已收到");
        udpClient.Send(response, response.Length, remoteEP);
        
        // 4. 关闭UdpClient
        udpClient.Close();
    }
}
        3、与Socket的对比
1、选择建议
1、使用TCPListener/UdpClient便于快速开发,适用简单通信需求,不需要特殊的Socket配置。
2、使用原生Socket需要精细控制网络行为,实现自定义协议,需要设置特殊Socket选项
2、实际应用建议
游戏类型选择:
回合制,卡牌类游戏优先选择TCP
实时动作类游戏优先选择UDP'
混合使用:
关键数据(如玩家状态)使用TCP
实时数据(如位置更新)使用UDP