在现代分布式系统中,不同服务之间需要高效、可靠的通信机制。Apache Thrift 是一个由 Facebook 开源的跨语言 RPC(远程过程调用)框架,支持包括 C、C++、Java、Python、Go 等数十种编程语言。本文将手把手教你如何在 C语言 中使用 Thrift 库,即使是编程小白也能轻松上手。
Thrift 的核心思想是:通过定义一套接口描述语言(IDL),自动生成客户端和服务端代码,从而实现跨语言通信。你只需编写一次接口定义,Thrift 编译器(thrift compiler)就能为你生成各种语言的绑定代码。
要使用 C 语言开发 Thrift 服务,你需要完成以下步骤:
以 Ubuntu/Debian 系统为例:
# 安装依赖sudo apt-get install build-essential libboost-dev libevent-dev# 下载并编译 Thrift(以 0.16.0 为例)wget https://archive.apache.org/dist/thrift/0.16.0/thrift-0.16.0.tar.gztar -xzf thrift-0.16.0.tar.gzcd thrift-0.16.0./configure --with-cpp --without-python --without-javamakesudo make install# 安装 C 语言运行时库sudo apt-get install libthrift-dev 创建一个名为 calculator.thrift 的文件,定义一个简单的计算器服务:
// calculator.thriftnamespace c calcenum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4}struct Work { 1: i32 num1, 2: i32 num2, 3: Operation op}service Calculator { i32 calculate(1: Work w), void ping()} 这里我们定义了一个 Calculator 服务,包含两个方法:calculate 和 ping。注意 namespace c calc 表示生成的 C 代码将放在 calc 命名空间下(在 C 中体现为前缀)。
运行 Thrift 编译器:
thrift --gen c calculator.thrift 执行后会生成 gen-c/ 目录,里面包含所有 C 语言所需的头文件和源文件,如 calc_calculator.h、calc_types.h 等。
创建 server.c 文件:
#include <thrift/c_glib/thrift.h>#include <thrift/c_glib/transport/thrift_server_socket.h>#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>#include "gen-c/calc_calculator.h"#include "gen-c/calc_types.h"// 实现 Calculator 接口typedef struct _CalculatorHandler CalculatorHandler;typedef struct _CalculatorHandlerClass CalculatorHandlerClass;struct _CalculatorHandler { GObject parent;};struct _CalculatorHandlerClass { GObjectClass parent_class;};G_DEFINE_TYPE(CalculatorHandler, calculator_handler, G_TYPE_OBJECT)static void calculator_handler_ping(ThriftIf *iface, GError **error) { g_print("ping() called\n");}static gint32 calculator_handler_calculate(ThriftIf *iface, gpointer w, GError **error) { Work *work = (Work *)w; switch (work->op) { case ADD: return work->num1 + work->num2; case SUBTRACT: return work->num1 - work->num2; case MULTIPLY: return work->num1 * work->num2; case DIVIDE: if (work->num2 == 0) { g_set_error(error, THRIFT_ERROR, THRIFT_ERROR_PROTOCOL, "Division by zero"); return 0; } return work->num1 / work->num2; default: g_set_error(error, THRIFT_ERROR, THRIFT_ERROR_PROTOCOL, "Invalid operation"); return 0; }}static void calculator_handler_init(CalculatorHandler *self) {}static void calculator_handler_class_init(CalculatorHandlerClass *klass) { ThriftIfClass *if_class = THRIFT_IF_CLASS(klass); if_class->ping = calculator_handler_ping; if_class->calculate = calculator_handler_calculate;}int main(void) { g_type_init(); CalculatorHandler *handler = g_object_new(TYPE_CALCULATOR_HANDLER, NULL); CalculatorProcessor *processor = calculator_processor_new(THRIFT_IF(handler)); ThriftServerTransport *server_transport = thrift_server_socket_new_with_host_port("localhost", 9090); ThriftTransportFactory *transport_factory = thrift_buffered_transport_factory_new(); ThriftProtocolFactory *protocol_factory = thrift_binary_protocol_factory_new(); ThriftSimpleServer *server = g_object_new(THRIFT_TYPE_SIMPLE_SERVER, "processor", processor, "server_transport", server_transport, "input_transport_factory", transport_factory, "output_transport_factory", transport_factory, "input_protocol_factory", protocol_factory, "output_protocol_factory", protocol_factory, NULL); g_print("Starting server on port 9090...\n"); thrift_server_serve(THRIFT_SERVER(server), NULL); g_object_unref(server); return 0;} 创建 client.c 文件:
#include <thrift/c_glib/thrift.h>#include <thrift/c_glib/transport/thrift_socket.h>#include <thrift/c_glib/transport/thrift_buffered_transport.h>#include <thrift/c_glib/protocol/thrift_binary_protocol.h>#include "gen-c/calc_calculator.h"#include "gen-c/calc_types.h"int main(void) { g_type_init(); ThriftSocket *socket = g_object_new(THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 9090, NULL); ThriftTransport *transport = thrift_buffered_transport_new(THRIFT_TRANSPORT(socket)); ThriftProtocol *protocol = thrift_binary_protocol_new(transport, transport); CalculatorClient *client = calculator_client_new(protocol); // 测试 ping calculator_client_ping(client, NULL); g_print("ping() success!\n"); // 测试 calculate Work *work = work_new(); work->num1 = 10; work->num2 = 5; work->op = ADD; gint32 result; calculator_client_calculate(client, &result, work, NULL); g_print("10 + 5 = %d\n", result); g_object_unref(client); return 0;} 使用以下命令编译服务端和客户端(假设所有文件在同一目录):
# 编译服务端gcc -o server server.c gen-c/*.c `pkg-config --cflags --libs thrift_c_glib`# 编译客户端gcc -o client client.c gen-c/*.c `pkg-config --cflags --libs thrift_c_glib` 先运行服务端:
./server 再打开另一个终端运行客户端:
./client 你应该看到输出:
ping() calledping() success!10 + 5 = 15 通过本教程,你已经学会了如何使用 C语言 Thrift 构建一个完整的 RPC 服务。Thrift 不仅支持 Apache Thrift C教程 中的基础功能,还能用于构建高性能的微服务系统。掌握 Thrift RPC C语言 开发技能,将帮助你在 C语言微服务通信 领域打下坚实基础。
虽然 C 语言的 Thrift 实现相对复杂(基于 GLib 对象系统),但其性能优异,适用于对资源敏感的嵌入式或高性能服务器场景。建议初学者先理解 IDL 定义和代码生成机制,再逐步深入服务端/客户端实现细节。
现在,你可以尝试扩展这个计算器服务,比如添加更多运算、错误处理或异步调用,进一步提升你的 Thrift 实战能力!
本文由主机测评网于2025-12-03发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025122249.html