Thrift的TJsonProtocol协议分析

时间:2023-02-02 08:48:46

Thrift协议实现目前有二进制协议(TBinaryProtocol),紧凑型二进制协议(TCompactProtocol)和Json协议(TJsonProtocol)。

前面的两篇文字从编码和协议原理方面分析了TBinaryProtocol和TCompactProtocol协议,下面对TJsonProtocol协议做一下分析。

TJsonProtocol协议相对比较简单,在网络中以文本方式传输,易于抓包分析和理解。

1. 数据类型表示方式和简写

数据类型
数据类型 Json协议节点简写 C++表示方式 Go表示方式 Java表示方式 Lua表示方式
布尔 tf bool bool boolean true/false
字节/8位 i8 int8_t,char int8 byte  
16位整数 i16 int16_t int16 short  
32位整数 i32 int32_t int32 int  
64位整数 i64 int64_t int64 long  
双精度小数 dbl double float64 double  
字符串 str string string String  
结构体 rec struct struct class table
列表 lst std:list<value> []type List<ValueType> table[value] = bool
集合 set std:set<value> map[ValueType]bool Set<ValueType> table[value] = bool
字典/映射 map std:map<key, value> map[KeyType]ValueType Map<KeyType,ValueType> table[key] = value

2.各数据类型表示方式

Thrift的TJsonProtocol协议分析

bool,i8,i16,i32,i64,double,string的Json表示格式:

"编号": {
"类型": "值"
},

结构体Json表示格式:

"编号": {
"rec": {
"成员编号": {
"成员类型": "成员值"
},
...
}
}

Map的Json表示格式:

"编号": {
"map": ["键类型",
"值类型",
元素个数,
{
"键1": "值1",
"键n": "值n"
}
]
},

Set和List的Json表示方式:

"编号": {
"set/lst": ["值类型",
元素个数,
"ele1",
"ele2",
"elen"
]
},

3. 编写Thrift的IDL文件并生成Golang代码

thrift --gen  go rpc.thrift

namespace go demo.rpc
namespace cpp demo.rpc
namespace java demo.rpc struct ArgStruct {
1:byte argByte,
2:string argString
3:i16 argI16,
4:i32 argI32,
5:i64 argI64,
6:double argDouble,
7:bool argBool,
} service RpcService {
list<string> funCall(
1:ArgStruct argStruct,
2:byte argByte,
3:i16 argI16,
4:i32 argI32,
5:i64 argI64,
6:double argDouble,
7:string argString,
8:map<string, string> paramMapStrStr,
9:map<i32, string> paramMapI32Str,
10:set<string> paramSetStr,
11:set<i64> paramSetI64,
12:list<string> paramListStr,
13:bool argBool,
),
}

编写客户端测试代码

package main

import (
"demo/rpc"
"fmt"
"git.apache.org/thrift.git/lib/go/thrift"
"net"
"os"
"time"
) func main() {
startTime := currentTimeMillis()
transportFactory := thrift.NewTTransportFactory()
protocolFactory := thrift.NewTJSONProtocolFactory() transport, err := thrift.NewTSocket(net.JoinHostPort("10.10.36.143", "8090"))
if err != nil {
fmt.Fprintln(os.Stderr, "error resolving address:", err)
os.Exit(1)
} useTransport := transportFactory.GetTransport(transport)
client := rpc.NewRpcServiceClientFactory(useTransport, protocolFactory)
if err := transport.Open(); err != nil {
fmt.Fprintln(os.Stderr, "Error opening socket to 127.0.0.1:19090", " ", err)
os.Exit(1)
}
defer transport.Close() for i := 0; i < 1000; i++ {
argStruct := &rpc.ArgStruct{}
argStruct.ArgByte = 53
argStruct.ArgString = "str value"
argStruct.ArgI16 = 54
argStruct.ArgI32 = 12
argStruct.ArgI64 = 43
argStruct.ArgDouble = 11.22
argStruct.ArgBool = true
paramMap := make(map[string]string)
paramMap["name"] = "namess"
paramMap["pass"] = "vpass"
paramMapI32Str := make(map[int32]string)
paramMapI32Str[10] = "val10"
paramMapI32Str[20] = "val20"
paramSetStr := make(map[string]bool)
paramSetStr["ele1"] = true
paramSetStr["ele2"] = true
paramSetStr["ele3"] = true
paramSetI64 := make(map[int64]bool)
paramSetI64[11] = true
paramSetI64[22] = true
paramSetI64[33] = true
paramListStr := []string{"l1.","l2."}
r1, e1 := client.FunCall(argStruct,
53, 54, 12, 34, 11.22, "login", paramMap,paramMapI32Str,
paramSetStr, paramSetI64, paramListStr, false)
fmt.Println(i, "Call->", r1, e1)
break
} endTime := currentTimeMillis()
fmt.Println("Program exit. time->", endTime, startTime, (endTime - startTime))
} // 转换成毫秒
func currentTimeMillis() int64 {
return time.Now().UnixNano() / 1000000
}

使用NewTJSONProtocolFactory方法使用Json协议。

编写服务段测试代码

package main

import (
"demo/rpc"
"fmt"
"git.apache.org/thrift.git/lib/go/thrift"
"os"
) const (
NetworkAddr = ":8090"
) type RpcServiceImpl struct {
} func (this *RpcServiceImpl) FunCall(argStruct *rpc.ArgStruct,
argByte int8, argI16 int16, argI32 int32,
argI64 int64, argDouble float64, argString string,
paramMapStrStr map[string]string, paramMapI32Str map[int32]string,
paramSetStr map[string]bool, paramSetI64 map[int64]bool,
paramListStr []string, argBool bool) (r []string, err error) {
fmt.Println("-->FunCall:", argStruct)
r = append(r, "return 1 by FunCall.")
r = append(r, "return 2 by FunCall.")
return
} func main() {
transportFactory := thrift.NewTTransportFactory()
protocolFactory := thrift.NewTJSONProtocolFactory() serverTransport, err := thrift.NewTServerSocket(NetworkAddr)
if err != nil {
fmt.Println("Error!", err)
os.Exit(1)
} handler := &RpcServiceImpl{}
processor := rpc.NewRpcServiceProcessor(handler) server := thrift.NewTSimpleServer4(processor, serverTransport,transportFactory, protocolFactory)
fmt.Println("thrift server in", NetworkAddr)
server.Serve()
}

使用NewTJSONProtocolFactory方法使用Json协议。

测试前抓包分析

请求报文:

[
1,
"funCall",
1,
1,
{
"1": {
"rec": {
"1": {
"i8": 53
},
"2": {
"str": "str value"
},
"3": {
"i16": 54
},
"4": {
"i32": 12
},
"5": {
"i64": 43
},
"6": {
"dbl": 11.22
},
"7": {
"tf": 1
}
}
},
"2": {
"i8": 53
},
"3": {
"i16": 54
},
"4": {
"i32": 12
},
"5": {
"i64": 34
},
"6": {
"dbl": 11.22
},
"7": {
"str": "login"
},
"8": {
"map": [
"str",
"str",
2,
{
"name": "namess",
"pass": "vpass"
}
]
},
"9": {
"map": [
"i32",
"str",
2,
{
"10": "val10",
"20": "val20"
}
]
},
"10": {
"set": [
"str",
3,
"ele1",
"ele2",
"ele3"
]
},
"11": {
"set": [
"i64",
3,
11,
22,
33
]
},
"12": {
"lst": [
"str",
2,
"l1.",
"l2."
]
},
"13": {
"tf": 0
}
}
]

  

请求报文分析:

一条消息用中括号 [] 括起来。

第1个元素1 表示协议版本,目前TJsonProtocol协议版本为1。

第2个元素funCall 表示消息的名称。

第3个元素1 表示消息请求,(消息请求:1,消息响应:2,消息异常:3,oneway消息:4)。

第4个元素1 表示消息流水号。

一条消息的参数用大括号{} 括起来。

消息参数的node键名称为thrift文件中定义的字段编号,node值由值类型和值组成。

如:

"1": {
"i8": 53
},

1 表示字段编号,i8表示值类型为8位整数或一个字节,53表示值。

其他也是同样的含义,不再赘述。

响应报文:

[
1,
"funCall",
2,
1,
{
"0": {
"lst": [
"str",
2,
"return 1 by FunCall.",
"return 2 by FunCall."
]
}
}
]

响应报文分析:

一条消息用中括号 [] 括起来。

第1个元素1 表示协议版本,目前TJsonProtocol协议版本为1。

第2个元素funCall 表示消息的名称。

第3个元素2 表示消息响应,(消息请求:1,消息响应:2,消息异常:3,oneway消息:4)。

第4个元素1 表示消息流水号。

接下来的字段是返回的参数。

Done.

Thrift的TJsonProtocol协议分析的更多相关文章

  1. Thrift的TBinaryProtocol二进制协议分析

    先上张图,说明一下thrift的二进制协议是什么东东. 报文格式编码: bool类型: 一个字节的类型,两个字节的字段编号,一个字节的值(true:1,false:0). Byte类型: 一个字节的类 ...

  2. Thrift的TCompactProtocol紧凑型二进制协议分析

    Thrift的紧凑型传输协议分析: 用一张图说明一下Thrift的TCompactProtocol中各个数据类型是怎么表示的. 报文格式编码: bool类型: 一个字节. 如果bool型的字段是结构体 ...

  3. Google的Protobuf协议分析

    protobuf和thrift类似,也是一个序列化的协议实现,简称PB(下文出现的PB代表protobuf). Github:https://github.com/google/protobuf 上图 ...

  4. 蓝牙协议分析&lpar;7&rpar;&lowbar;BLE连接有关的技术分析

    转自:http://www.wowotech.net/bluetooth/ble_connection.html#comments 1. 前言 了解蓝牙的人都知道,在经典蓝牙中,保持连接(Connec ...

  5. 协议分析TMP

    最近闲来有事, 分析了一个非常低端(非常低端的意思是说你不应该对她是否能取代你现有的QQ客户端作任何可能的奢望,她只是一个实验性的东西)的手机QQ的协议, 是手机QQ3.0,      所用到的TCP ...

  6. 协议分析 - DHCP协议解码详解

    协议分析 - DHCP协议解码详解 [DHCP协议简介]         DHCP,全称是 Dynamic Host Configuration Protocol﹐中文名为动态主机配置协议,它的前身是 ...

  7. PYTHON黑帽编程1&period;5 使用WIRESHARK练习网络协议分析

    Python黑帽编程1.5  使用Wireshark练习网络协议分析 1.5.0.1  本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks At ...

  8. BT协议分析&lpar;1&rpar;&mdash&semi;1&period;0协议

    简述 BT下载是采用P2P的下载方式,下载的大致形式采用如下图所示,处于图示中心的称为Tracker服务器,其余称为Peer.   缺点 1.资源的安全性 2.资源的实效性(没有上传者则BT也将失效) ...

  9. Memcache的使用和协议分析详解

    Memcache的使用和协议分析详解 作者:heiyeluren博客:http://blog.csdn.NET/heiyeshuwu时间:2006-11-12关键字:PHP Memcache Linu ...

随机推荐

  1. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  2. 控制TextField的内容长度

    参考如下代码(下例是控制设置交易密码,控制6位): - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [ ...

  3. nyoj 14 会场安排问题(贪心专题)

    会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工 ...

  4. 51nod 1445 变色DNA&lpar;dij&rpar;

    题目链接:51nod 1445 变色DNA 看了相关讨论再去用最短路:val[i][j]之间如果是'Y',说明i可以到达j,并且i到达j的代价是i那行 1到j-1 里面'Y'的数量. 最后,求 0到n ...

  5. &lbrace;Reship&rcub;Precision&comma; Accuracy &amp&semi; Recall

    ============================================================== This aritcle came from here ========= ...

  6. 如何去设计一个自适应的网页设计或HTMl5

    如何去设计一个自适应的网页设计或HTMl5 如今移动互联网随着3G的普及,越来越火爆,更多需求跟随而来!APP应用市场和APP应用数量成倍成倍的增长!从而给移动互联网带来新的挑战! 移动设备正超过桌面 ...

  7. 大学生学习编程&lpar;PHP&rpar;

    在v2ex上看到一大三的求职实习,然后有人给出了建议,个人觉得也挺好,做个记录./  原帖地址 @ARjson问: 大三的学生党,求实习岗位,现居北京.后端PHP一年半开发经验,熟悉speedphp, ...

  8. 智能手机取证利器再进化-UFED Cloud Analyzer

    智能手机在现代人生活中,和钱包,钥匙一样,成了不可或缺的生活必需品,举凡食衣住行育乐都需要携带随身使用,因此,智能手机里所存放的,就是一个人的生活缩影,只是人们多半不自知智能手机竟是如此贴心的为你/妳 ...

  9. cmd的copy命令合并多个文件

    1.1个a.jpg文件:1个b.php文件(一句话木马)

  10. 三维偏序-二维LIS

    Another Longest Increasing Subsequence Problem 有两种思路. 思路一: 考虑到如果只有一维,那么可以用f[s]表示长度为s时,最后一个数是多少,把这个想法 ...