Linux 使用thrift进行java和c++之间调用

项目需要,文件拼接检查这块使用的c语言完成的,项目是java的项目,考虑过jni调用,但存在c代码异常导致jvm崩溃问题,故采用thrift进行调用,保证java项目运行稳定,

        拼接检查的接口是

#define FILE_CONCAT_DETECTION_H

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

struct file_concat_entry
{
    char *type;
    off_t beg_pos;
    off_t end_pos;
};

/**
 * @brief file_concat_detection_buf
 * @param buf
 * @param len
 * @param off
 * @param entries
 * @return 出错返回-1, 其它表示entries的数量, 用户需要free entries避免内存泄露
 */
int file_concat_detection_buf(char *buf, off_t len, off_t off, struct file_concat_entry **entries);

int file_concat_detection(char *pathname, off_t off, struct file_concat_entry **entries);

#ifdef __cplusplus
}
#endif

#endif // FILE_CONCAT_DETECTION_H

 thrift接口为

namespace cpp FileConcat

// 定义错误异常
exception FileConcatError {
    1: string message
}

// 定义文件合并条目结构
struct FileConcatEntry {
    1: string type,           // 使用 string 代替 char*
    2: i64 beg_pos,          // 使用 i64 代替 off_t
    3: i64 end_pos           // 使用 i64 代替 off_t
}

// 定义服务
service FileConcatService {
    // 文件合并检测
    list<FileConcatEntry> detection_buf(1: binary buf, 2: i64 len, 3: i64 off) throws (1: FileConcatError e);
    list<FileConcatEntry> detection(1: string pathname, 2: i64 off) throws (1: FileConcatError e);
}


开发环境是UOS,首先按照thrift相关,boost在另一台机器上只安装了libboost-dev,没有问题

sudo apt install thrift-compiler
sudo apt install libthrift-dev
sudo apt install libboost-all-dev

执行 thrift --gen cpp FileConcat.thrift,执行完成后生成gen-cpp目录,里面有几个.cpp和.h文件,我这不的机器上thrift版本

另一个debian的机器thrift按照的版本是0.17.0,gen-cpp里面的文件有区别。

编写server端的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/FileConcatService.h"
#include "detector.h"

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace FileConcat;

class FileConcatServiceHandler : public FileConcatServiceIf {
public:
    // Implement the file_concat_detection_buf method
    void detection_buf(std::vector<FileConcatEntry> & _return, const std::string& buf, const int64_t len, const int64_t off) override {
        printf("detect buf strlen:%d, len: %ld, off: %ld\n", strlen(buf.c_str()), len, off);
        struct file_concat_entry *centries = NULL;
        int num_entries = file_concat_detection_buf((char *)buf.c_str(), len, off, &centries);
        if (num_entries == -1)
        {
            printf("file concat dection error");
            FileConcatError e;
            e.message = "file concat dection error.";
            throw e;
        }

        for (int i=0; i<num_entries; i++)
        {
            printf("\tfind file: %s, beg: %ld, end: %ld, size: %ld\n", centries[i].type, centries[i].beg_pos, centries[i].end_pos, centries[i].end_pos-centries[i].beg_pos);
            FileConcatEntry entry;
            entry.beg_pos = centries[i].beg_pos;
            entry.end_pos = centries[i].end_pos;
            entry.type = centries[i].type;
            _return.push_back(entry);
        }

        free(centries);
    }

    // Implement the file_concat_detection method
    void detection(std::vector<FileConcatEntry> & _return, const std::string& pathname, const int64_t off) override {
        struct file_concat_entry *centries = NULL;
        int num_entries = file_concat_detection((char *)pathname.c_str(), off, &centries);
        if (num_entries == -1)
        {
            printf("file concat dection error");
            FileConcatError e;
            e.message = "file concat dection error.";
            throw e; // Throw exception on error
        }

        printf("file concat dectect: %s, off: %ld\n", pathname.c_str(), off);

        for (int i=0; i<num_entries; i++)
        {
            printf("\tfind file: %s, beg: %ld, end: %ld, size: %ld\n", centries[i].type, centries[i].beg_pos, centries[i].end_pos, centries[i].end_pos-centries[i].beg_pos);
            FileConcatEntry entry;
            entry.beg_pos = centries[i].beg_pos;
            entry.end_pos = centries[i].end_pos;
            entry.type = centries[i].type;
            _return.push_back(entry);
        }

        free(centries);
    }
};


int main(int argc, char** argv) {
    int port = 9090;

    ::std::shared_ptr<FileConcatServiceHandler> handler(new FileConcatServiceHandler());
    ::std::shared_ptr<TProcessor> processor(new FileConcatServiceProcessor(handler));
    ::std::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    ::std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    ::std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());


    TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
    printf("Starting the server on port %d...\n", port);
    server.serve();
    return 0;
}

 使用g++做为编译器,链接thrift库

g++ FileConcatServer.cpp gen-cpp/FileConcatService.cpp gen-cpp/FileConcat_constants.cpp gen-cpp/FileConcat_types.cpp -o ../bin/fileconcatdetectionserver -I/usr/include/thrift -lthrift -L../bin -lfileconcatdetection

 得到fileconcatdetectionserver可执行程序,运行如下

 

 下面编写java端的client代码,

首先是执行thrift --gen java FileConcat.thrift,执行完后产生gen-java目录,里面有三个java文件,复制到项目中

pom文件中添加thrift依赖

    <dependencies>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.9.3</version>
        </dependency>
    </dependencies>

编写java代码

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

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {

        System.out.println("Hello world shit!");
        TTransport transport = null;
        try {
            transport = new TSocket("localhost", 9090);
            transport.open();
            TBinaryProtocol protocol = new TBinaryProtocol(transport);
            FileConcatService.Client client = new FileConcatService.Client(protocol);

            // 调用服务
//            int result = client.detection_buf("buffer data", 100, 0, entries);
//            System.out.println("Result: " + result);
            byte[] byteArray = new byte[]{1, 2, 3, 4, 5}; // 示例 byte 数组

            // 将 byte[] 转换为 ByteBuffer
            ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
            List<FileConcatEntry> r = client.detection_buf(byteBuffer, 5, 5);
            List<FileConcatEntry>  result = client.detection("/home/xxxx/Desktop/SpFileInspector/bin/hello_rar_test_doc.rar", 0);
            System.out.println("Result: ");
            for (FileConcatEntry entry: result)
            {
                System.out.println("type: " + entry.getType()+" ,beg:" + entry.getBeg_pos()+" ,end:"+entry.getEnd_pos());
            }

        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (transport != null) {
                transport.close();
            }
        }
    }
}

java运行效果

c++的server运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值