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

相关推荐
weixin_520649874 小时前
WinForm数据展示组件ListView
c#
码途漫谈4 小时前
Easy-Vibe开发篇阅读笔记(四)——前端开发之结合 Agent Skills 美化界面
人工智能·笔记·ai·开源·ai编程
酿情师5 小时前
yihan:一款面向连续网页学习的智能侧边栏插件
学习·学习方法·工具·学习工具
瞎某某Blinder6 小时前
DFT学习记录[6]基于 HES06的能带计算+有效质量计算
python·学习·程序人生·数据挖掘·云计算·学习方法
love在水一方7 小时前
VLN 入门学习计划 —— 基于 InternNav
学习
糖炒栗子03267 小时前
【笔记】高分卫星影像 TIF 切片处理
笔记
Nice_Fold7 小时前
Kubernetes DaemonSet、StatefulSet与Service(自用笔记)
笔记·容器·kubernetes
程序设计实验室9 小时前
Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。
c#
red_redemption9 小时前
自由学习记录(175)
学习
ZhiqianXia10 小时前
《The Design of Design》阅读笔记
前端·笔记·microsoft