在网络通讯中应用Protobuf

Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强;还有一个比较大的优点就是有着很多的语言平台支持。下面讲解一下如何在TCP通讯应用中集成Protobuf.

Protobuf提供一种简单的对象消息方式来描述数据的存储,通过相关实现可以简单地实现数据流和对象之间的转换。但由于Protobuf序列化后的信息并不包括一些相应对象类型描述,只有消息体的内容;因此在进行通信交互过程中默认情况是不知道这些数据和对象的对应关系;既然对方不清楚这些数据对应那种类型,那数据还源成对象就根本没办法入手。所以把Protobuf用到网络通讯中我们还需要外加一些协议来规范数据的对应关系。

在通讯协议上只需要在消息体中先写入类型然后再写入Protobuf数据,TypeName主要是用于对方配匹数据对应的对象关系,这个TypeName是string还是int或其他就根据自己喜好来制定了。

在通讯上问题就解决了,但还要面对实际中使用的一种情况消息太多了……那处理TypeName->Object则一个蛋痛的事情。还好在.net和android下有类元素表这玩意还能在运行行进行操作,从而可以大大节省这些if判断处理。由于本人熟悉的语言平台有限,在这里分别提供java和c#的解决方法。

  • Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void Register(Class<?> protobufclass) {
        try {
            ProtoMessageHandler mb;
            Class<?>[] protoObjs = protobufclass.getClasses();
            for (Class<?> item : protoObjs) {
                if(item==null)
                    continue;
                if (!item.isInterface() && item.getSuperclass().equals(
                        com.google.protobuf.GeneratedMessage.class)) {
                    mb = new ProtoMessageHandler();
                    mb.SetType(item);
                    mMessageTbl.put(item.getSimpleName(), mb);
                }
            }
        } catch (Exception e) {
             
             
        }
 
    }

由于使用Protoc工具生成的类都会生成一个大类里,所以只需要注册指定的类然后对所有继承com.google.protobuf.GeneratedMessage的内嵌类找出来并记录在一个Map中即可。

1
2
3
4
5
String name= stream.ReadUTF();
        ProtoMessageHandler handler = ProtoPackage.GetMsgHandler(name);
        if(handler==null)
            throw new Exception(name+" message type notfound!");
        Message=(com.google.protobuf.GeneratedMessage) handler.GetObject(stream.GetStream());

以上是通过类型值获取对应的对象,并填充Protobuf数据。

  • c#

相对于android平台下的实现,.net的实现就更简单些了。

1
2
3
4
5
6
7
8
public static void Register(System.Reflection.Assembly assembly)
        {
            foreach(Type type in assembly.GetTypes())
            {
                if (!type.IsAbstract && !type.IsInterface && type.GetCustomAttributes(typeof(ProtoBuf.ProtoContractAttribute), false).Length > 0)
                    mProtoTbl[type.Name] = type;
            }
        }
1
2
3
string name = reader.ReadUTF();
            Type type = ProtoPakcage.GetProtoType(name);
            Message = ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(reader.Stream, null, type);

通过以上方法在使用Protobuf的时候就不用担心消息太多写if写到手软了,也不容易出错。不过有一点要注意的就是类的名称一定要对应,否则就无法匹配到消息了。如果想得到完全整的代码可以到https://beetlenp.codeplex.com获取。

在网络通讯中应用Protobuf的更多相关文章

  1. 网络通讯中 bind函数的作用

    面向连接的网络应用程序分为客户端和服务器端.服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤. 服务器端执行流程4步如下: (1)调用socket函数,建立一个套接字,该套接字用于接 ...

  2. Qt的Model/View Framework解析(数据是从真正的“肉(raw)”里取得,Model提供肉,所以读写文件、操作数据库、网络通讯等一系列与数据打交道的工作就在model中做了)

    最近在看Qt的Model/View Framework,在网上搜了搜,好像中文的除了几篇翻译没有什么有价值的文章.E文的除了Qt的官方介绍,其它文章也很少.看到一个老外在blog中写道Model/Vi ...

  3. 【咸鱼教程】protobuf在websocket通讯中的使用

    教程目录一 protobuf简介二 使用protobuf三 Demo下载 参考: CSDN:Egret项目中使用protobuf(protobufjs) TS项目中使用Protobuf的解决方案(ba ...

  4. Linux系统网络编程中TCP通讯socket--send导致进程被关闭

    https://blog.csdn.net/dsanmux/article/details/52083403 https://blog.csdn.net/u011425939/article/deta ...

  5. [dotnet core]使用Peach简化Socket网络通讯协议开发

    Peach是基于DotNetty的Socket网络通讯帮助类库,可以帮助开发者简化使用DotNetty,关于DotNetty可参考我之前的这篇文章. Peach内置实现了一个基于文本协议的Comman ...

  6. 网络通讯之Socket-Tcp(二)

    网络通讯之Socket-Tcp  分成2部分讲解: 网络通讯之Socket-Tcp(一): 1.如何理解Socket 2.Socket通信重要函数 3.Socket Tcp 调用的基本流程图 4.简单 ...

  7. 《连载 | 物联网框架ServerSuperIO教程》-4.如开发一套设备驱动,同时支持串口和网络通讯。附:将来支持Windows 10 IOT

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  8. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  9. Windows 网络通讯开发

    Windows 网络通讯开发 一.Windows网络开发API 由于C++标准库中没有网络库,所以进行网络开发的时候要调用系统API.Windows通讯开发API包括以下几个基本函数及成员类型: 1. ...

随机推荐

  1. SpringMVC4 + Spring + MyBatis3

    SpringMVC4 + Spring + MyBatis3 本文使用最新版本(4.1.5)的springmvc+spring+mybatis,采用最间的配置方式来进行搭建. 1. web.xml 我 ...

  2. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

  3. 【百度地图API】暑假放假回老家——城市切换功能

    原文:[百度地图API]暑假放假回老家--城市切换功能 任务描述: 酸奶小妹放寒假啦,要从北京呼啦一下飞回重庆呢.现在百度地图API上不能直接切换城市,怎么办呢? 如何实现: 利用API先搜索到要去城 ...

  4. CSS3+HTML5特效3 - 纵向无缝滚动

    老惯例,先看例子. This is a test 1. This is a test 2. This is a test 3. This is a test 4. This is a test 5. ...

  5. Google maps API开发

    原文:Google maps API开发 Google maps API开发(一) 最近做一个小东西用到google map,突击了一下,收获不小,把自己学习的一些小例子记录下来吧 一.加载Googl ...

  6. 判断文件是否存在,不存在创建文件&&判断文件夹是否存在,不存在创建文件夹

    1.判断文件是否存在,不存在创建文件 File file=new File("C:\\Users\\QPING\\Desktop\\JavaScript\\2.htm"); if( ...

  7. sax(用于处理XML事件驱动的推模型)解析例子

    SAX解析 Java程序如下: import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; impor ...

  8. PHP激活用户注册验证邮箱

    本文将结合实例介绍如何使用PHP+Mysql完成注册帐号.发送激活邮件.验证激活帐号.处理URL链接过期的功能. 注册邮箱激活流程 <ul class='ul_demo''> <li ...

  9. loadrunner常用函数总结

    事务函数:lr_end_sub_transaction 标记子事务的结束以便进行性能分析lr_end_transaction 标记 LoadRunner 事务的结束lr_end_transaction ...

  10. 学习的例子gcc+gdb+make

    1 小侃GCC 在正式使用gcc之前,我们先来侃侃gcc是啥玩意儿? 历史 如今的GCC是GNU Compiler Collection的简称.既然是Collection,就是指一些工具链的集合. 最 ...