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日

相关文章

  • asp.net(c#)限制用户输入规定的字符和数字的代码

    ASP.NET(C#)限制用户输入规定的字符和数字是一种常见的输入检查要求。可以通过正则表达式在前端或后端实现此功能。本文将介绍如何在 ASP.NET(C#) 中使用正则表达式限制用户输入规定的字符和数字,包括过程和示例。 步骤一:导入正则表达式命名空间 正则表达式命名空间是 System.Text.RegularExpressions。在 C# 应用程序中…

    C# 2023年5月31日
    00
  • C#通过NPOI导入导出数据EXCEL

    下面是关于“C#通过NPOI导入导出数据EXCEL”的完整攻略,包含以下几个部分: NPOI简介 导出Excel 导入Excel 示例说明 1. NPOI简介 NPOI是一个开源的.NET库,可以用来读写Microsoft Excel、Word和PowerPoint格式的文件。对于需要在C#中读写Excel文件的开发者来说,NPOI是一个不错的选择。使用NP…

    C# 2023年5月31日
    00
  • ASP.NET(AJAX+JSON)实现对象调用

    ASP.NET是Microsoft公司推出的一款用于创建动态Web应用程序的框架,支持多种编程语言(如C#和VB.NET)。AJAX和JSON都是前端开发中常用的技术,AJAX技术可以实现异步数据通信,JSON则是一种轻量级的数据交换格式。 ASP.NET结合AJAX和JSON技术可以实现对象调用,以下是具体步骤: 创建一个Web应用程序,并在项目中添加必要…

    C# 2023年5月31日
    00
  • C#实现类型的比较示例详解

    C#实现类型的比较示例详解 引言 C#是一门强类型的语言,在C#中,我们需要对不同的数据类型进行比较。因此,C#提供了多种方法来进行类型的比较。本文将介绍C#中实现类型比较的方法。 基本类型的比较 在C#中,基本类型的比较可以直接使用“==”和“!=”运算符。下面是一个示例: int a = 10; int b = 20; bool result = a =…

    C# 2023年5月14日
    00
  • C# WinForm实现自动更新程序之客户端的示例代码

    好的!本文将详细讲解“C# WinForm实现自动更新程序之客户端的示例代码”的完整攻略,包括以下内容: 前置知识 客户端代码示例 示例说明 前置知识 在讲解“C# WinForm实现自动更新程序之客户端的示例代码”之前,需要掌握一些前置知识: C#语言的基础语法 WinForm应用程序的基础知识 HTTP协议的基本原理及其在.NET中的应用 XML文档的基…

    C# 2023年6月1日
    00
  • asp.net配置会话状态Session实现代码

    下面我会给出详细讲解“asp.net配置会话状态Session实现代码”的完整攻略。 准备工作 在开始编写会话状态的代码之前,我们需要进行如下准备工作: 确定会话过期的时间。默认情况下,会话过期时间是20分钟。 配置Web.config文件。我们可以通过配置Web.config文件来改变会话过期时间等属性。 配置过期时间 我们可以通过在Web.config文…

    C# 2023年5月31日
    00
  • C# String.Split()方法: 按指定的分隔符将字符串分成一个字符串数组

    String.Split()方法是C#中用于将字符串按照指定的字符或字符串分割成子字符串的方法。具体来说,Split()方法会根据指定的分隔符将原字符串分割成多个子字符串,并返回一个字符串类型的数组,数组中的每个元素都是一个分割后的子字符串。 Split()方法有多种重载形式,下面分别介绍常用的两个重载形式。 1. Split(char[] separato…

    C# 2023年4月19日
    00
  • C#实现将记事本中的代码编译成可执行文件的方法

    下面是“C#实现将记事本中的代码编译成可执行文件的方法”的完整攻略,包含两条实例说明。 步骤一:编写源代码 首先需要编写C#源代码,可使用记事本或任意一种文本编辑器。下面是一个简单的示例: using System; namespace HelloWorld { class Program { static void Main(string[] args) …

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