C++实现gRPC通信需四步:1.定义.proto接口;2.用protoc生成C++代码;3.继承Service类实现服务端;4.通过Stub编写客户端调用,注意编译时链接gRPC和Protobuf库。

用 C++ 实现 gRPC RPC 通信,核心是定义协议(.proto)、生成 C++ 代码、实现服务端逻辑、编写客户端调用。整个流程不复杂但需注意编译依赖和运行时链接。
1. 定义 .proto 接口文件
先写一个 helloworld.proto,声明服务和消息结构:
syntax = "proto3";
<p>package helloworld;</p><p>// 请求和响应消息
message HelloRequest {
string name = 1;
}</p><p>message HelloReply {
string message = 1;
}</p><p>// 定义 RPC 方法
service Greeter {
rpc SayHello(HelloRequest) returns (HelloReply) {}
}
</p>这个文件描述了“客户端传名字,服务端回欢迎语”的简单交互。
立即学习“C++免费学习笔记(深入)”;
2. 生成 C++ 代码
用 protoc 和 gRPC 插件生成头文件与源文件:
- 安装 protoc 和 grpc_cpp_plugin(通常随 gRPC 源码或包管理器安装)
- 执行命令(假设 protoc 在 PATH 中):
protoc -I . --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
会生成 helloworld.pb.h/.cc(数据序列化)和 helloworld.grpc.pb.h/.cc(服务桩)。
3. 编写服务端(Server)
继承生成的 Greeter::Service 类,重写 SayHello 方法:
#include "helloworld.grpc.pb.h"
#include <iostream>
#include <memory>
#include <string>
<p>class GreeterServiceImpl final : public helloworld::Greeter::Service {
public:
grpc::Status SayHello(grpc::ServerContext<em> context,
const helloworld::HelloRequest</em> request,
helloworld::HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return grpc::Status::OK;
}
};</p><p>int main() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;</p><p>grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);</p><p>std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait(); // 阻塞等待
}
</p>关键点:使用 InsecureServerCredentials() 表示明文通信;若需 TLS,改用 SslServerCredentials 并提供证书。
4. 编写客户端(Client)
用生成的 stub 调用远程方法:
#include "helloworld.grpc.pb.h"
#include <iostream>
#include <memory>
#include <string>
<p>int main(int argc, char** argv) {
std::string target_str = "localhost:50051";
GreeterClient client(
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));</p><p>std::string user("world");
std::string reply = client.SayHello(user);
std::cout << "Got reply: " << reply << std::endl;
return 0;
}</p><p>// 辅助类封装 stub 调用
class GreeterClient {
public:
explicit GreeterClient(std::shared<em>ptr<grpc::Channel> channel)
: stub</em>(helloworld::Greeter::NewStub(channel)) {}</p><p>std::string SayHello(const std::string& user) {
helloworld::HelloRequest request;
request.set_name(user);</p><pre class="brush:php;toolbar:false;">helloworld::HelloReply reply;
grpc::ClientContext context;
grpc::Status status = stub_->SayHello(&context, request, &reply);
if (status.ok()) {
return reply.message();
} else {
return "RPC failed: " + status.error_message();
}}
private: std::uniqueptr<:greeter::stub> stub; };
注意:客户端也用 InsecureChannelCredentials() 对应服务端的不安全模式;异步调用可改用 AsyncStub。
5. 编译与运行
需链接 gRPC 和 Protobuf 库(以 CMake 为例):
find_package(gRPC CONFIG REQUIRED) find_package(Protobuf REQUIRED) <p>add_executable(server server.cpp helloworld.pb.cc helloworld.grpc.pb.cc) target_link_libraries(server PRIVATE grpc++ grpc++_reflection protobuf::libprotobuf)</p><p>add_executable(client client.cpp helloworld.pb.cc helloworld.grpc.pb.cc) target_link_libraries(client PRIVATE grpc++ protobuf::libprotobuf) </p>
确保环境已安装 gRPC(推荐用 官方源码编译 或 vcpkg/conan 管理)。运行时先启动 server,再运行 client。










