Unity3D C# Socket通信详解之Protobuf.net使用详解


1 介绍

Protobuf实际是一套类似Json或者XML的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的message数据结构进行打包,然后编译成二进制的码流再进行传输或者存储。

protobuf全称Protocol Buffers,简称GPB、PB,是QQ等IM采用的协议,比XML、XMPP(环信)、JSON、结构体等所有传输效果都高的一种传输协议,由谷歌发明,其效率一般是XM的20倍以上,JSON的10倍以上,是一种游戏中普遍采用的消息协议。

简单说就是Google公司发明的,用来进行序列化和反序列化的。
和json、xml类似,Protobuf有几个突出的优点:

  • 序列化后的数据更小,消息大小只需要XML的1/10 ~ 1/3
  • 解析速度更快,解析速度比XML快20 ~ 100倍
  • 兼容性更好,可以很好的向上或向下兼容
  • 跨平台的,只需定义一份proto文件,即可编译成各种语言的源码

当然,其也有一定的缺点:由于序列化为了二进制数组,序列化后完全不可读。

Protobuf-Net是Marc Gravell在protobuf基础上修改的.net版本,相比Google的代码,其在.Net环境下使用起来更加简单。本篇文章就介绍一下Protobuf的使用。
Protobuf-Net的Github地址

2 Protobuf-Net的使用

2.1 安装

我们在进行vs开发的时候,安装Protobuf-Net很简单,直接在Nuget包管理器中搜索Protobuf-Net即可。
如图。
1.进入包管理器进入包管理器
2.搜索Protobuf-Net,并安装
Protobuf-Net的安装

2.2 语法

2.2.1 序列化

核心代码就是Serializer.Serialize方法,该方法有两个参数,第二个参数是要序列化的对象,第一个参数是要序列化到的流对象。
例如序列化FileSteam,序列化完成后将直接保存至本地,不必再调用fs.Write、fs.Flush等方法。

using (FileStream fs = File.Create(path))
{
    Serializer.Serialize(fs, t);
}

也可使用MemoryStram配合Protobuf-Net来实现对象的深拷贝,就是先将要拷贝的对象序列化然后在反序列化出来。

public static T Clone<T>(T t)
{
    using (MemoryStream ms = new MemoryStream())
    {
        Serializer.Serialize(ms, t);
        ms.Position = 0;
        return Serializer.Deserialize<T>(ms);
    }
}

或者直接使用Serializer.DeepClone(t)方法(其内部实现与上面我们的方法相同)。

2.2.2 反序列化

反序列化也很简单,核心代码是Serializer.Deserialize(),传入流对象,即可得到反序列化后的对象。
如反序列化文件。

public static T Read<T>(string path)
{
    using (FileStream fs = File.OpenRead(path))
    {
        return Serializer.Deserialize<T>(fs);
    }
}

2.2.3 类处理

对于需要序列化的类,需要添加上对应的特性。
一是给类添加[ProtoBuf.ProtoContract]特性,类中的字段或属性添加[ProtoBuf.ProtoMember(1)]特性。
如下:

[ProtoBuf.ProtoContract]
internal class Student : Pearson
{
    [ProtoBuf.ProtoMember(1, IsRequired = true)]
    public int Id { get; set; }

    public Student() { }

    public override string ToString()
    {
        return $"id:{Id} name:{Name} age:{Age} gender:{Gender}";
    }
}

其中[ProtoBuf.ProtoMember(1, IsRequired = true)],数字1表示tag,只能为正数,建议从1开始;IsRequired表示是否必要,方便向后兼容,什么意思呢?比方说我们之前发布了一个版本,协议已经定好,现在需要在类中添加一些内容,这些内容就需要加上IsRequired = false,这样我们的程序虽然添加了新的内容,但是仍然可以打开之前的数据而不会报错

二是在有继承的情况时,基类需要添加上[ProtoBuf.ProtoInclude(100, typeof(Student))]特性。
一个基类可能有多个子类,有几个子类,基类上就添加几个[ProtoBuf.ProtoInclude(100, typeof(Student))]。
其中的100也是tag,和ProtoBuf.ProtoMember的tag类似,但是ProtoBuf.ProtoInclude的tag要是唯一的,不能和基类上其他的ProtoBuf.ProtoInclude的tag相同,也不能和基类中的ProtoBuf.ProtoMember的tag相同。typeof(T),表示已知的子类。

public enum Gender
{
    Male,
    Female
}

[ProtoBuf.ProtoContract]
[ProtoBuf.ProtoInclude(100, typeof(Student))]
[ProtoBuf.ProtoInclude(101, typeof(Teacher))]	// 如这里tag不能设为100、1、2、3
class Pearson
{
    [ProtoBuf.ProtoMember(1, IsRequired = false)]
    public string Name { get; set; }
    [ProtoBuf.ProtoMember(2, IsRequired = true)]
    public Gender Gender { get; set; }
    [ProtoBuf.ProtoMember(3, IsRequired = true)]
    public int Age { get; set; }
}

完整的测试项目在这。
链接:https://pan.baidu.com/s/16ri31b8F2UxvR5IDxbQP_A
提取码:5sky

3 Unity下使用Protobuf-Net

TODO 待完成。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity是一款跨平台的游戏开发引擎,而Protobuf是一种用于序列化结构化数据的协议,Socket是一种在网络通信使用的编程接口。 Unity使用ProtobufSocket可以实现网络通信功能。首先,我们可以使用Protobuf来定义网络通信中传输的数据结构和协议格式。Protobuf支持在不同的编程语言间进行数据交换,因此很方便地在Unity使用。 通过Socket编程接口,Unity可以实现与远程服务器或其他客户端之间的网络通信使用SocketUnity可以发送和接收经由Protobuf序列化的数据,从而实现与其他设备或服务器的数据交换。 使用Unity+Protobuf+Socket,我们可以实现一些功能,如多人在线游戏、实时数据同步、远程调用等。例如,在多人在线游戏中,我们可以使用Socket建立客户端与服务器之间的连接,通过Protobuf序列化游戏数据,通过Socket传输数据到服务器或其他玩家端,从而实现玩家之间的实时交互。 总而言之,Unity+Protobuf+Socket的组合可以帮助我们实现高效的网络通信,并且为游戏开发提供了很多有用的工具和功能。 ### 回答2: Unity是一款强大的游戏开发引擎,能够创建各种类型的游戏和应用程序。ProtobufProtocol Buffers)是一种高效的数据序列化和传输格式,它可以将结构化数据转换成二进制形式,使得数据的传输和存储更加高效。Socket则是一种用于在计算机网络中进行进程间通信的一种方式。 在Unity使用ProtobufSocket可以实现高效的网络通信。首先,我们可以使用Protobuf来定义数据的结构和格式,通过定义消息的字段和类型,可以在客户端和服务器端之间传输和解析数据。Protobuf不仅提供了简洁的消息描述语言,还提供了代码生成器来生成针对不同编程语言的序列化和反序列化代码。 然后,我们可以使用Socket来建立网络连接,并通过发送和接收数据来进行通信Socket可以实现同步和异步的通信方式,可以在客户端和服务器端之间实时地传输数据。通过将Protobuf序列化的数据通过Socket发送,接收方可以解析并处理这些数据。 Unity中的Socket编程可以使用C#Socket类库来实现。通过创建socket对象,可以实现网络连接的建立和维护。然后可以使用Socket发送和接收数据,通过将Protobuf序列化的数据进行编码和解码,从而实现数据的传输和解析。 总结起来,Unity使用ProtobufSocket可以实现高效的网络通信,通过定义消息的结构、通过Socket建立连接、通过Protobuf进行数据的序列化和反序列化,可以实现客户端和服务器端之间的实时通信。这种方式能够提高网络传输的效率,减少带宽和资源的消耗,使得游戏和应用程序具有更好的性能和用户体验。 ### 回答3: Unity是一款跨平台的游戏开发引擎,Protobuf是Google开发的一种数据序列化的格式,而Socket是一种用于网络通信的API。 在Unity使用Protobuf可以帮助我们更方便地处理网络数据的序列化和反序列化。Protobuf可以将结构化的数据转换为二进制格式,从而提高数据传输的效率和安全性。Unity提供了对Protobuf的支持,我们可以在项目中导入Protobuf的文件,并使用Protobuf的工具生成相应的编解码类来进行数据的序列化和反序列化操作。 Socket则是网络编程中常用的通信方式之一,它提供了一种用于网络通信的API,可以实现不同设备之间的数据传输。在Unity使用Socket可以实现客户端与服务器之间的实时通信。我们可以使用Socket来建立连接、发送和接收数据,并进行相应的处理。通过Socket使用,可以在Unity中实现诸如多人游戏、聊天系统等功能。 在Unity中结合使用ProtobufSocket可以实现高效、安全的网络通信。我们可以使用Protobuf对数据进行序列化和反序列化操作,然后通过Socket进行数据的传输。这样可以确保数据的准确性和安全性。例如,在游戏中,我们可以使用Protobuf将玩家的位置信息、操作指令等数据序列化为二进制格式,然后通过Socket发送给服务器或其他玩家,再由接收端使用Socket进行数据的解析和处理。这样可以实现多人游戏中的实时同步,增加游戏的可玩性和互动性。 综上所述,Unity中的ProtobufSocket可以在游戏开发中起到重要的作用。Protobuf可以帮助我们方便地进行数据的序列化和反序列化操作,而Socket可以实现跨设备的网络通信。它们的结合使用可以实现高效、安全的网络通信,为游戏开发提供便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值