C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信

C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信

简介

Protocol Buffer(又称protobuf)是Google开发的一种数据序列化格式,它比XML和JSON更快、更小、更简单。由于最初是用于Google内部的系统和数据通信,并且其生成和解析代码性能优秀,因此被开源出来,可供广泛的应用使用。

Unity 的网络通信有多种方式,传统的网络通信方式使用的是二进制通信,Protocol Buffer 序列化后的数据包十分小巧,带来了传输效率的很大提升。本文介绍了如何使用 C# 库在 Unity 中进行 Protocol Buffer 序列化及网络通信。

使用ProtoBuf进行数据序列化

首先,需要引入 protobuf 的库文件,可以通过NuGet等工具来安装Protobuf-net,它是一个比较普及的C#的protobuf序列化库,有很好的公共库支持,适合Unity项目使用。

打开 Visual Studio 或者 Visual Studio Code 在项目的引用中添加 protobuf 库

using ProtoBuf;
using System;
[ProtoContract]
public class UserInfo
{
    [ProtoMember(1)]
    public int Id { get; set; }

    [ProtoMember(2)]
    public string Name { get; set; }
}

上述代码中,我们定义了一个名为 UserInfo 的类,加上 ProtoContract 标签,这是 protobuf 序列化的必要标记。同时,类中的属性也需要使用 ProtoMember 标签标注一下,用来指定属性序列化后的标记数字。

当类规模非常大的时候,我们可以通过 ProtoInclude 标签将已有的消息类型引入到消息基类中,从而减少代码量和工作量。

[ProtoContract]
[ProtoInclude(1, typeof(UserInfo))]
public abstract class BaseMessage
{

}

使用ProtoBuf进行网络通信

在 Unity 中实现 Socket 通信无外乎两个关键步骤:客户端向服务端发送消息、服务端收到消息并进行处理并向客户端回复消息。

客户端向服务端发送消息

客户端向服务端发送消息时,需使用 Socket 建立连接,然后将请求数据序列化后发送到服务端。

public class Client : MonoBehaviour
{
    void Start()
    {
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888));

        UserInfo userInfo = new UserInfo { Id = 1, Name = "Debra" };
        byte[] buffer;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize(ms, userInfo);
            buffer = ms.ToArray();
        }

        socket.Send(buffer);
    }
}

在上面的代码中,我们首先使用 Socket.Connect() 方法将客户端连接到指定的 IP 和端口上,接着我们创建一个 UserInfo 实例,在下一步中将其序列化成我们期望的二进制格式,最后使用 Socket.Send() 方法将请求数据发送到服务端。

服务端收到消息并进行处理并向客户端回复消息

当服务端接收到客户端的请求消息后,服务端需要先解析该请求消息,~~处理逻辑~~ ,制作响应消息并将响应消息序列化后返回给客户端。

public class Server : MonoBehaviour
{
    void Start()
    {
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888));
        socket.Listen(0);
        Socket clientSocket = socket.Accept();

        byte[] buffer = new byte[1024];
        int length = clientSocket.Receive(buffer);
        byte[] data = new byte[length];
        Array.Copy(buffer, data, length);

        UserInfo userInfo = null;
        using (MemoryStream ms = new MemoryStream(data))
        {
            userInfo = Serializer.Deserialize<UserInfo>(ms);
        }

        //处理逻辑
        userInfo.Name = userInfo.Name + "hello";

        byte[] sendBuffer;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize(ms, userInfo);
            sendBuffer = ms.ToArray();
        }

        clientSocket.Send(sendBuffer);
        clientSocket.Close();
    }
}

在上述代码中,首先我们创建一个 Socket 执行 listen 监听,当客户端连接后,则会产生一个新的客户端socket。接着,我们使用客户端socket的 Receive() 方法来接收客户端发来的请求,同样需要将接收到的数据进行反序列化,接下来进行我们期望的业务逻辑处理来生成响应(在这个例子中,只是在UserName 末尾添加了“hello”的字样表示已经处理好了响应)。最后将这个响应数据通过 Socket.Send() 发送给客户端。

示例说明

在示例代码中,我们首先创建了一个 UserInfo 类作为 protobuf 的序列化格式,之后定义了一个 Server 和一个 Client 来表示服务端和客户端。在具体的执行中,服务端首先使用 Socket.Bind() 方法将服务器绑定到指定的端口,接着使用 Socket.Listen() 来启动监听。当客户端连接到服务端时,服务端则会调用 Socket.Accept() 方法并返回一个新的客户端Socket,之后通过该客户端 Socket 来接收客户端发来的请求。服务端处理完逻辑后,将响应数据序列化,并通过客户端Socket.Send() 将响应数据回传给客户端。 客户端则负责将请求数据序列化,并调用 Socket.Send() 方法向服务端发送请求数据。

总结

使用 protobuf 序列化技术来进行网络通信是一种非常良好的解决方案,它克服了二进制数据格式和传送速度之间的矛盾。在Unity中使用protobuf,不仅可以提高我们代码的执行效率,还可以提升我们的通信性能和体验。在实际项目中,借助 protobuf 进行数据序列化来进行通信,不仅可以进行各种尝试和创新,还有助于保障网络通信的质量、稳定性和安全性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • C#实现简单的JSON序列化功能代码实例

    下面给出C#实现简单的JSON序列化功能的完整攻略,包含以下几个步骤: 1. 创建C#类以及对象 首先需要创建一个C#类,该类的属性用于存储需要序列化成JSON格式的数据。以下是一个示例类: public class Person { public string Name { get; set; } public int Age { get; set; } …

    C# 2023年5月31日
    00
  • C# Linq的Zip()方法 – 将两个序列中的对应元素组合成一个新的序列

    下面是关于C# Linq的Zip()方法的详细攻略: 什么是Zip()方法 Zip()方法是LINQ操作中的一种,它接收两个序列作为参数,将这两个序列的对应元素合并在一起,并返回一个新的序列。 这个方法在处理数据时非常有用,例如,我们可以使用Zip()从两个数组中创建一个“键值对”,或者从两个不同的列表中提取相关数据。 Zip()方法的语法和用法 Zip()…

    C# 2023年4月19日
    00
  • C#实现求一组数据众数的方法

    要实现求一组数据的众数,可以采用以下步骤: 步骤一:读入数据 首先要将一组数据读入程序中,可以使用数组、列表等数据结构来存储数据。 示例代码: int[] data = { 2, 3, 2, 4, 5, 2, 1 }; 步骤二:找出出现次数最多的数 通过遍历数组或列表,统计每个数出现的次数,并记录出现次数最多的数。 示例代码: int maxCount = …

    C# 2023年6月7日
    00
  • C#将数字转换成字节数组的方法

    要将一个数字转换成字节数组,我们可以使用C#中的BitConverter.GetBytes方法。该方法接受一个long,int,short,ulong,uint,ushort,double,float或decimal型式的数字,并将其转换为字节数组。 具体步骤如下: 使用BitConverter.GetBytes方法将数字转换为字节数组。例如: int nu…

    C# 2023年6月7日
    00
  • ASP.NET Core 实现基本认证的示例代码

    当我们需要给我们的Web应用程序添加身份验证功能时,可以使用ASP.NET Core来实现,ASP.NET Core实现身份验证的主要方法是使用中间件,即Microsoft.AspNetCore.Authentication中的中间件。 在此,我将介绍如何使用ASP.NET Core来实现基本身份验证,并提供两个示例说明。 实现基本身份验证的示例代码 1. …

    C# 2023年5月31日
    00
  • .NET Core部署到linux(CentOS)最全解决方案,常规篇

    本文为大家介绍使用 .NET Core部署到Linux服务器的方法,通过本文你将了解到Linux在虚拟机下的安装、Xshell,Xftp的使用方法、git在linux下的交互使用以及.net core在linux下的发布与运行全过程,本文皆在总结了一些经验与笔记在部署过程中遇到的一些问题,同时分享给大家,供大家参考,欢迎讨论交流。 1、Linux操作系统、X…

    C# 2023年5月5日
    00
  • 用Fine Uploader+ASP.NET MVC实现ajax文件上传[代码示例]

    使用Fine Uploader和ASP.NET MVC实现ajax文件上传是一项非常常见的任务。下面是实现这个任务的完整攻略: 步骤一:安装Fine Uploader 首先,需要从Fine Uploader的官方网站下载Fine Uploader。然后,将下载的Fine Uploader文件解压缩到您的应用程序中。 步骤二:设置文件上传 在您的ASP.NET…

    C# 2023年5月31日
    00
  • 在C#中如何使用Dapper详解(译)

    以下是关于“在C#中如何使用 Dapper”的详细攻略: 1. 什么是 Dapper? Dapper 是一个简单、轻量级的 .NET ORM 框架,与其他相似的框架相比,它的性能更高、更稳定,支持多种数据库,包括 SQL Server、MySQL、PostgreSQL 等。 2. 如何使用 Dapper? 首先,我们需要安装 Dapper,可以通过 NuGe…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部