Unity Socket学习笔记 (三)TCP&UDP

文章目录


一、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

相关推荐
Lhappy嘻嘻2 小时前
Java IO|File 文件操作 + 字节流 / 字符流完整笔记 + 递归删除文件实战
java·笔记·php
GLDbalala5 小时前
GPU PRO 5 - 4.6 Adaptive Scalable Texture Compression 笔记
笔记
xian_wwq5 小时前
【学习笔记】模型权重管理:Safetensors与私有化Hub(23/35)
笔记·学习
逝水无殇5 小时前
C# 异常处理详解
开发语言·后端·c#
其实防守也摸鱼5 小时前
运维--学习阶段问题解答(1)(自测)
linux·运维·服务器·数据库·学习·自动化·命令模式
ctrl_v助手5 小时前
Halcon学习笔记2
人工智能·笔记·学习
YUS云生6 小时前
Python学习笔记·第31天:FastAPI入门——路由、路径参数、查询参数与请求体
笔记·python·学习
玖玥拾6 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾7 小时前
Rust 学习目录
开发语言·学习·rust
逝水无殇7 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#