thrift demo

1 thrift 环境搭建

Windows thrift 下载
thrift 各版本下载链接
使用thrift -gen 生成代码
demo.thrift文件内容:

namespace java demo.thrift
service demo{
 string helloString(1:string para)
}

将下载的thrift-0.14.1.exe 文件放置在一文件夹中,将编写好的demo.thrift文件放置在同一路径。
执行生成代码命令

 .\thrift-0.14.1.exe -gen java .\demo.thrift

会在当前路径下生成一个gen-java目录,里面有demo.java文件。

2 编写代码

java中使用thrift,依赖相关的jar包。使用IDEA创建maven工程,引入Thrift包。
pom.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>org.example</groupId>
    <artifactId>ThriftDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
 
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.thrift/libthrift -->
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.13.0</version>
        </dependency>
    </dependencies>
</project>

将生成的demo.java文件放置在/src/main/java目录下。
另外编写 demoImpl.java、Server.java、Client.java文件。
在demoImpl.java中编写服务逻辑,示例代码如下:

import org.apache.thrift.TException;

public class DemoImpl implements demo.Iface {
    @Override
    public String helloString(String username) throws TException {
        return "Hello " + username;
    }
}

在Server.java中编写服务端程序:

import hello.DemoImpl;
import hello.demo;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import java.net.ServerSocket;


public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(9003);
        TServerSocket serverTransport = new TServerSocket(serverSocket);
        demo.Processor processor =
                new demo.Processor<demo.Iface>(new DemoImpl());
        TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
        TSimpleServer.Args tArgs = new TSimpleServer.Args(serverTransport);
        tArgs.processor(processor);
        tArgs.protocolFactory(protocolFactory);

        // 简单的单线程服务模型 一般用于测试
        TServer tServer = new TSimpleServer(tArgs);
        System.out.println("Running Simple Server");
        tServer.serve();
    }
}

在Client.java中编写客户端程序:

import hello.demo;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

public class SimpleClient {
    public static void main(String[] args) {
        TTransport transport = null;
        try {
            transport = new TSocket("localhost", 9003);
            TProtocol protocol = new TBinaryProtocol(transport);
            demo.Client client = new demo.Client(protocol);
            transport.open();
            String result = client.helloString("world");
            System.out.println("Result =: " + result);
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }
}

3 运行

首先将server端代码运行起来,然后执行客户端。
客户端正常打印:
Result =: Hello world

4 抓包分析

抓包工具wireshak安装
wireshark官方下载链接
抓包工具使用
step1 选择使用的接口,点击start

step2 输入过滤规则,点击过滤
tcp && (tcp.srcport == 9003 || tcp.dstport == 9003) # 监控tcp协议9003端口数据

step3 启动服务端,启动客户端

step4 二进制协议解析
消息类型:

类型 二进制 十进制
Call 001 1
Reply 010 2
Exception 011 3
Oneway 100 4

数据类型:

类型 十进制
STOP 0
VOID 1
BOOL 2
BYTE 3
DOUBLE 4
I16 6
I32 8
I64 10
STRING 11
STRUCT 12
MAP 13
SET 14
LIST 15
ENUM 16

TCP协议传输的数据(payload):

8001 0001 0000000b 68656c6c6f537472696e67 00000001 0b 0001 00000004 7a6c7373 00

字段 说明
8001 协议版本号
0001 前8位按照协议规定未被使用,后8位中的最后三位指定消息类型
0000000b 消息类型后面的32位数据定义了服务名称的长度
68656C6C6F537472696E67 utf-8解码:helloString
00000001 seq id,在其之后传输的就是具体数据
0b 数据解析时,默认先读取一个字节,确定数据类型
0001 两个字节的编号,指明这段数据在结构体中的位置
00000004 如果是String类型,在其后4个字节给出Sting的长度
7a6c7373 utf-8解码:zlss
00 表示Stop,结束位

参考链接

环境搭建参考链接
抓包分析
抓包环境搭建

posted @ 2022-09-09 16:35  柳叶昶  阅读(89)  评论(0编辑  收藏  举报