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

相关推荐
今天只学一颗糖3 小时前
Linux学习笔记--触摸屏驱动
笔记·学习
Gin3873 小时前
mooc自动互评脚本笔记---2025年10月11日
笔记
半路程序员3 小时前
Go语言学习(四)
开发语言·学习·golang
蒙奇D索大4 小时前
【C语言加油站】C语言文件操作详解:从“流”的概念到文件的打开与关闭
c语言·开发语言·笔记·学习·改行学it
摇滚侠4 小时前
Spring Boot 3零基础教程,依赖管理机制,笔记06
spring boot·笔记·后端
数据库生产实战4 小时前
Oracle LOB使用入门和简单使用,提供学习用的测试用例!
数据库·学习·oracle
聪明的笨猪猪5 小时前
Java Spring “事务” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
爱喝水的鱼丶5 小时前
SAP-ABAP:SAP中的用户确认对话框:深入理解与实践POPUP_TO_CONFIRM
运维·开发语言·学习·sap·abap
lingggggaaaa5 小时前
小迪安全学习笔记(一百零二讲)—— 漏扫项目篇&PoC开发&Yaml语法&插件一键生成&匹配结果&交互提取
笔记·学习·安全·网络安全·交互