跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

gRPC 跨语言通信实战:C++ 服务端与 C# 客户端

综述由AI生成gRPC 跨语言通信基于 HTTP/2 和 Protocol Buffers。演示使用 C++ 构建服务端、C# 构建客户端的完整流程。包括环境配置、proto 文件定义、代码生成、服务逻辑实现及编译运行。涵盖连接失败、序列化错误等常见问题排查,以及性能优化建议。通过 Calculator 服务示例验证了加法和减法运算的远程调用,展示了微服务架构下的高效通信方案。

鲜活发布于 2026/3/26更新于 2026/5/2214 浏览
gRPC 跨语言通信实战:C++ 服务端与 C# 客户端

前言

在现代分布式系统中,gRPC 作为高性能、跨语言的 RPC 框架越来越受欢迎。它基于 HTTP/2 协议,使用 Protocol Buffers(Protobuf)作为接口定义语言,支持多种编程语言,能够高效地实现不同语言之间的远程过程调用。

一、环境准备

必要工具安装
1. Protocol Buffers 编译器 (protoc)

Protocol Buffers 是一种轻便高效的结构化数据存储格式,gRPC 使用它来定义服务接口和数据结构。你需要下载并安装 Protocol Buffers 编译器 protoc,下载地址为:https://github.com/protocolbuffers/protobuf/releases。安装完成后,确保将 protoc 添加到系统的 PATH 环境变量中,这样在命令行中就可以直接使用它。

2. gRPC 相关工具(C++)

对于 C++ 开发,你需要安装 gRPC 和 protobuf 库。在 Ubuntu 系统上,可以使用以下命令进行安装:

sudo apt install libgrpc++-dev libprotobuf-dev protobuf-compiler grpc-plugins
3. .NET 环境

C# 开发需要安装 .NET SDK(版本 ≥ 6.0),你可以从 https://dotnet.microsoft.com/download 下载并安装。安装完成后,在 C# 项目中添加必要的 NuGet 包:

dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools

二、定义服务接口

创建 proto 文件

首先,我们需要创建一个 .proto 文件来定义服务接口和数据结构。创建一个名为 sample_service.proto 的文件,内容如下:

syntax = "proto3";
option csharp_namespace = "SampleService.Client";
package sampleservice;

// 请求消息
message CalculationRequest {
  double a = 1;
  double b = 2;
}

// 响应消息
message CalculationResult {
  double result = 1;
}

// 服务定义
service Calculator {
  // 加法运算
  rpc Add (CalculationRequest) returns (CalculationResult);
  // 减法运算
  rpc Subtract (CalculationRequest) returns (CalculationResult);
}

在这个 .proto 文件中,我们定义了一个名为 Calculator 的服务,包含两个方法:Add 和 Subtract,分别用于执行加法和减法运算。同时,我们还定义了请求消息 CalculationRequest 和响应消息 CalculationResult。

三、C++ 服务端实现

1. 生成 gRPC 代码

为了根据 .proto 文件生成 C++ 代码,我们需要创建一个脚本 generate.sh:

#!/bin/bash
protoc -I=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` sample_service.proto
protoc -I=. --cpp_out=. sample_service.proto

运行这个脚本后,会生成以下文件:

  • sample_service.grpc.pb.h:包含服务接口的定义。
  • sample_service.grpc.pb.cc:服务接口的实现代码。
  • sample_service.pb.h:消息类型的定义。
  • sample_service.pb.cc:消息类型的实现代码。
2. 实现服务逻辑

创建 calculator_service.h 文件,实现服务逻辑的头文件:

#include <grpcpp/grpcpp.h>
#include "sample_service.grpc.pb.h"
using grpc::ServerContext;
using grpc::Status;
using sampleservice::CalculationRequest;
using sampleservice::CalculationResult;
using sampleservice::Calculator;

class CalculatorServiceImpl final : public Calculator::Service {
public:
    Status Add(ServerContext* context, const CalculationRequest* request, CalculationResult* response) override;
    Status Subtract(ServerContext* context, const CalculationRequest* request, CalculationResult* response) override;
};

然后,创建 calculator_service.cpp 文件,实现具体的服务逻辑:

#include "calculator_service.h"

Status CalculatorServiceImpl::Add(ServerContext* context, const CalculationRequest* request, CalculationResult* response) {
    double result = request->a() + request->b();
    response->set_result(result);
    return Status::OK;
}

Status CalculatorServiceImpl::Subtract(ServerContext* context, const CalculationRequest* request, CalculationResult* response) {
    double result = request->a() - request->b();
    response->set_result(result);
    return Status::OK;
}
3. 实现服务端主程序

创建 server.cpp 文件,实现服务端的主程序:

#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "calculator_service.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

void RunServer() {
    std::string server_address("0.0.0.0:50051");
    CalculatorServiceImpl service;
    ServerBuilder builder;
    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
    builder.RegisterService(&service);
    std::unique_ptr<Server> server(builder.BuildAndStart());
    std::cout << "Server listening on " << server_address << std::endl;
    server->Wait();
}

int main() {
    RunServer();
    return 0;
}
4. 编译服务端

为了编译服务端代码,我们需要创建一个 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.10)
project(grpc_server)
set(CMAKE_CXX_STANDARD 17)
find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)
add_executable(server server.cpp calculator_service.cpp sample_service.pb.cc sample_service.grpc.pb.cc)
target_link_libraries(server PRIVATE gRPC::grpc++ gRPC::grpc protobuf::libprotobuf)

然后,按照以下步骤进行编译和运行:

mkdir build && cd build
cmake .. && make
./server

四、C# 客户端实现

1. 创建 C# 项目

使用以下命令创建一个新的 C# 控制台项目:

dotnet new console -n GrpcClient
cd GrpcClient
dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
2. 添加 proto 文件

将之前创建的 sample_service.proto 文件复制到 C# 项目目录下,并修改 .csproj 文件,添加以下内容:

<ItemGroup>
  <Protobuf Include="sample_service.proto" GrpcServices="Client" />
</ItemGroup>
3. 实现客户端

修改 Program.cs 文件,实现客户端代码:

using System;
using System.Threading.Tasks;
using Grpc.Net.Client;
using SampleService.Client;

class Program {
    static async Task Main(string[] args) {
        using var channel = GrpcChannel.ForAddress("http://localhost:50051");
        var client = new Calculator.CalculatorClient(channel);
        try {
            // 加法示例
            var addRequest = new CalculationRequest { A = 5, B = 3 };
            var addResult = await client.AddAsync(addRequest);
            Console.WriteLine($"5 + 3 = {addResult.Result}");
            
            // 减法示例
            var subRequest = new CalculationRequest { A = 10, B = 4 };
            var subResult = await client.SubtractAsync(subRequest);
            Console.WriteLine($"10 - 4 = {subResult.Result}");
        } catch (Grpc.Core.RpcException ex) {
            Console.WriteLine($"RPC failed: {ex.Status.Detail}");
        }
    }
}
4. 运行客户端

在项目目录下,使用以下命令运行客户端:

dotnet run

五、测试与验证

1. 启动 C++ 服务端

在终端中运行编译好的服务端程序:

./server

服务端启动后,会监听 0.0.0.0:50051 端口。

2. 运行 C# 客户端

在另一个终端中,进入 C# 客户端项目目录,运行客户端程序:

dotnet run

如果一切正常,你将看到以下输出:

5 + 3 = 8
10 - 4 = 6

这表明客户端成功调用了服务端的方法,并得到了正确的结果。

六、常见问题解决

1. 连接失败
  • 确保服务端地址正确:检查客户端代码中指定的服务端地址和端口是否与服务端实际监听的地址和端口一致。
  • 检查防火墙设置:确保防火墙没有阻止客户端与服务端之间的通信。可以临时关闭防火墙进行测试,或者在防火墙中开放相应的端口。
  • 服务端和客户端使用相同的协议:确保客户端和服务端使用相同的协议(HTTP/HTTPS)。如果服务端使用的是不安全连接(InsecureServerCredentials),客户端也应该使用不安全连接。
2. 序列化错误
  • 确保 proto 文件在服务端和客户端完全一致:.proto 文件是服务端和客户端通信的契约,必须保证两端的 .proto 文件内容完全相同。
  • 重新生成代码后清理并重新编译:如果修改了 .proto 文件,需要重新生成代码,并清理和重新编译服务端和客户端项目。
3. 性能优化
  • 对于高频调用,考虑使用连接池:gRPC 本身没有提供连接池的功能,但可以通过第三方库或自定义实现来实现连接池,以减少连接建立和销毁的开销。
  • 调整 gRPC 通道参数:可以根据实际情况调整 gRPC 通道的参数,如超时时间、最大消息大小等,以提高性能。

七、流程总结

以下是按照步骤,用表格形式总结的基于 gRPC 实现跨语言通信(C++ 服务端、C# 客户端)的流程:

gRPC 跨语言通信实现流程总结表
步骤任务具体内容详细描述
1. 环境准备安装必要的工具和库安装 Protocol Buffers 编译器(protoc),如在 Windows 系统中下载安装包并配置环境变量,使其可在命令行中直接调用;安装 gRPC 相关工具,包括 gRPC 插件(如 grpc_cpp_plugin 和 grpc_csharp_plugin),用于生成对应语言的源代码;安装.NET 环境(如.NET SDK),用于 C# 客户端开发,可通过官网下载对应版本安装包并安装,安装完成后可通过命令行运行 dotnet --version 验证安装是否成功;此外,还需安装 C++ 开发环境(如 Visual Studio),用于 C++ 服务端的开发,安装时选择对应的开发工作负载,如'桌面开发'等
2. 定义服务接口使用.proto文件定义服务接口和数据结构创建.proto文件来定义服务接口及数据结构,例如定义一个名为 Calculator 的服务,其中包含 Add 和 Subtract 方法,该方法接收一个 CalculationRequest 消息类型作为参数,并返回一个 CalculationResult 消息类型,.proto 文件中会包含对应的 message 定义来具体描述 CalculationRequest 和 CalculationResult 的字段,如 double a 和 double b 字段等
3. 生成代码根据.proto文件生成 C++ 和 C# 代码在命令行中使用 protoc 编译器,结合相应的 gRPC 插件来生成代码,对于 C++,运行类似 protoc --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin path/to/your/service.proto 的命令,生成 C++ 服务端的桩代码;对于 C#,通过 NuGet 包 Grpc.Tools 自动处理 proto 文件的编译,生成 C# 客户端的存根代码
4. 实现服务端在 C++ 中实现服务端逻辑,并编译运行根据生成的 C++ 桩代码,在 C++ 项目中实现服务端的具体逻辑,如实现 Calculator 服务中的 Add 方法的业务逻辑,编写一个 Add 的重写方法,在该方法中根据输入的 CalculationRequest 来构造 CalculationResult 作为返回值;之后配置 C++ 项目的编译链接环境,添加必要的 gRPC、Protocol Buffers 库依赖等,编译生成服务端可执行文件,并运行服务端
5. 实现客户端在 C# 中实现客户端代码,并运行客户端进行测试根据生成的 C# 存根代码,在 C# 项目(如使用.NET SDK 创建的控制台应用程序项目)中实现客户端逻辑,创建 Channel 连接到服务端地址,创建客户端实例,并调用服务端的方法,如调用 Add 方法,构造 CalculationRequest 并发送请求,接收服务端返回的 CalculationResult;配置 C# 项目依赖,添加 gRPC、Protocol Buffers 相关的 NuGet 包引用,运行客户端进行测试
6. 测试与验证启动服务端和客户端,验证通信是否正常先启动服务端,确保服务端处于运行状态并监听端口;然后启动客户端,客户端会发送请求到服务端,服务端处理后返回响应给客户端,观察客户端是否能正确接收到预期的响应结果,如在控制台输出计算结果来验证通信是否成功
7. 问题解决遇到问题时,根据具体情况进行排查和解决如果服务端和客户端无法通信,可以检查网络连接是否正常,如端口是否被正确监听和连接;检查服务端和客户端的 .proto 文件版本是否一致,以及生成的代码是否正确;检查是否所有必要的依赖库都已正确安装和配置;通过查看日志信息、调试程序等方式来定位问题并解决,根据问题具体表现来逐步排查原因

希望这个表格能帮助你清晰地梳理整个 gRPC 跨语言通信实现的流程。

通过以上步骤,我们完成了一个完整的 gRPC 跨语言通信系统的搭建,实现了 C++ 服务端和 C# 客户端之间的通信。这个示例展示了 gRPC 的核心功能,你可以基于此扩展更复杂的业务逻辑。gRPC 的强大之处在于它的跨语言特性和高性能通信能力,非常适合微服务架构。

目录

  1. 前言
  2. 一、环境准备
  3. 必要工具安装
  4. 1. Protocol Buffers 编译器 (protoc)
  5. 2. gRPC 相关工具(C++)
  6. 3. .NET 环境
  7. 二、定义服务接口
  8. 创建 proto 文件
  9. 三、C++ 服务端实现
  10. 1. 生成 gRPC 代码
  11. 2. 实现服务逻辑
  12. 3. 实现服务端主程序
  13. 4. 编译服务端
  14. 四、C# 客户端实现
  15. 1. 创建 C# 项目
  16. 2. 添加 proto 文件
  17. 3. 实现客户端
  18. 4. 运行客户端
  19. 五、测试与验证
  20. 1. 启动 C++ 服务端
  21. 2. 运行 C# 客户端
  22. 六、常见问题解决
  23. 1. 连接失败
  24. 2. 序列化错误
  25. 3. 性能优化
  26. 七、流程总结
  27. gRPC 跨语言通信实现流程总结表
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • MySQL 数据类型详解:从数值到字符串的实战指南
  • 从 MySQL 迁移到国产数据库的真实笔记:坑点与优化
  • IPv6+DDNS-GO 连接故障排查与三种替代方案对比
  • LLM 常见归一化方法解析:LayerNorm、RMSNorm 与 DeepNorm
  • Java Web 开发入门:基础概念、环境搭建与 Servlet/JSP
  • C++ 异常处理机制:从基础到实践的全面解析
  • 国内如何升级 GitHub Copilot 到专业版
  • C++ STL 容器适配器详解:stack、queue 与 priority_queue 原理
  • 基于 FastAPI 的 Web 上位机系统设计与实战
  • Kotlin 注解详解:声明、应用与元注解
  • EpicDesigner 低代码设计器配置与使用指南
  • 基于 FastAPI 的 Web 上位机系统设计与实现
  • 前端面试核心问题整理:Vue、React、Node.js 与工程化实践
  • Java 数据结构:HashMap 与 TreeMap 区别及 Map 与 Set 关系
  • C++驱动 spidev0.0 时 read 函数返回 255 的硬件电平分析
  • Kimi 新模型 K2.5 多模态与编程能力实测
  • Windows Git Bash 下安装 tmux 实现 SSH 会话保持
  • Ubuntu 部署 Claude Code 及 Web 界面完整指南
  • Arduino BLDC 自适应阻抗控制外骨骼机器人
  • C++ 入门:引用、内联函数与 C++11 新特性详解

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online