首页 > 编程语言 >rust可以和C语言程序使用grpc进行通信吗? rust是客户端,C是服务端。 如果可以的话,举一个简单的例子,需要给出具体的代码。

rust可以和C语言程序使用grpc进行通信吗? rust是客户端,C是服务端。 如果可以的话,举一个简单的例子,需要给出具体的代码。

时间:2024-12-17 18:52:53浏览次数:5  
标签:grpc helloworld server Rust rust C语言 服务端 客户端

是的,Rust 可以与 C 语言程序通过 gRPC 进行通信。gRPC 是一个语言中立的通信框架,支持多种语言之间的互操作,包括 Rust 和 C。

关键步骤概述:

  1. 定义 gRPC 接口(.proto 文件): 定义服务端和客户端之间的接口。
  2. C 服务端实现: 使用 C 语言实现服务端,处理客户端的请求。
  3. Rust 客户端实现: 使用 Rust 调用服务端提供的接口。

步骤 1:定义 gRPC 接口

创建一个 helloworld.proto 文件,定义服务端和客户端接口:

syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

步骤 2:C 语言服务端实现

首先,我们需要将 .proto 文件转换为 C 语言可使用的接口定义。

  1. 安装 gRPC 和 Protobuf 工具:

  2. 生成 C 语言代码:
    使用 protoc 编译器生成 C 语言代码:

    protoc --grpc_out=. --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin helloworld.proto
    protoc --cpp_out=. helloworld.proto
    
  3. C 服务端代码:

    在 C 中实现服务端(假设生成的代码在 helloworld.grpc.pb.chelloworld.pb.c 文件中):

#include <grpc/grpc.h>
#include <grpc/impl/codegen/status.h>
#include <grpc/pprof.h>
#include <helloworld.grpc.pb.h>
#include <stdio.h>
#include <string.h>

void SayHello(grpc_server *server, grpc_context *ctx, grpc_call *call) {
    HelloRequest req;
    HelloResponse res;
    
    // 读取请求数据
    grpc_call_read(call, &req);
    
    // 构造响应消息
    const char *response_msg = "Hello, ";
    snprintf(res.message, sizeof(res.message), "%s%s!", response_msg, req.name);
    
    // 发送响应
    grpc_call_send_response(call, &res);
}

int main(int argc, char **argv) {
    grpc_server *server = grpc_server_create();
    
    grpc_server_add_service(server, &Greeter_service);
    
    grpc_server_start(server, "localhost:50051");
    
    printf("Server started, listening on 50051\n");
    grpc_server_run(server);  // Blocking, will wait until terminated
    return 0;
}

步骤 3:Rust 客户端实现

  1. 添加依赖:

    Cargo.toml 中添加 tonicprost 依赖:

    [dependencies]
    tonic = "0.6"
    prost = "0.10"
    tokio = { version = "1", features = ["full"] }
    
  2. 生成 Rust 代码:
    使用 prosttonic 工具生成 Rust 的服务代码。

    build.rs 中指定生成代码:

    fn main() {
        tonic_build::compile_protos("proto/helloworld.proto")
            .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
    }
    

    然后创建 proto/helloworld.proto 文件并运行:

    cargo build
    

    这将生成 Rust 代码。

  3. Rust 客户端代码:

    main.rs 中实现客户端:

use tonic::transport::Channel;
use helloworld::greeter_client::GreeterClient;
use helloworld::HelloRequest;

pub mod helloworld {
    tonic::include_proto!("helloworld");
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GreeterClient::connect("http://localhost:50051").await?;

    let request = tonic::Request::new(HelloRequest {
        name: "World".into(),
    });

    let response = client.say_hello(request).await?;

    println!("RESPONSE={:?}", response.into_inner().message);

    Ok(())
}

步骤 4:运行客户端和服务端

  1. 运行 C 服务端:

    编译并运行 C 语言服务端:

    gcc -o server server.c -lgrpc++ -lprotobuf
    ./server
    

    这将启动一个 gRPC 服务端,监听在 localhost:50051 上。

  2. 运行 Rust 客户端:

    在 Rust 项目中运行客户端:

    cargo run
    

    客户端将通过 gRPC 向服务端发送请求,服务端处理后返回响应,客户端会输出响应信息。

总结:

通过上述步骤,你可以让 Rust 客户端与 C 语言服务端通过 gRPC 进行通信。gRPC 提供了语言中立的协议(通过 .proto 文件定义),使得 Rust 和 C 语言可以轻松互操作。

如果你遇到问题或需要进一步的帮助,随时告诉我!

标签:grpc,helloworld,server,Rust,rust,C语言,服务端,客户端
From: https://www.cnblogs.com/Tifahfyf/p/18613248

相关文章

  • c语言链表头插法再汇总
    建议回顾c链表一系列操作(主要是尾插法)c链表头插法遍历函数在这里先把尾插法的遍历函数稍作修改拿过来。voidForeach(NODE*h){if(NULL==h){return;}//辅助指针变量(帽子)NODE*pC=h;//这里改动是因为没有第一个空节点了......
  • c++领域展开第四幕——类和对象(上篇收尾 this指针、c++和c语言的初步对比)超详细!!!!
    文章目录前言一、this指针二、c++和c语言的初步对比总结前言上篇我们初步学习了类的基本概念以及实例化今天我们来学习类的构造以及析构还有类的默认成员函数,类和对象这一部分都会有点难跟着我一起来吧一、this指针Date类中有Init与Print两个成员函数,函......
  • 初探C语言|用C语言实现扫雷游戏的底层逻辑
    文章目录前言游戏规则理清思路代码实现主函数代码test()menue()game()游戏代码初始化棋盘打印棋盘布置雷排查雷+判断输赢完整代码测试test.c封装头文件game.h封装函数game.c拓展实现:欢迎讨论:如有错误或不足,欢迎指正和建议,本人主打“听劝”。当然,如有疑问,也期待你......
  • 【C语言】· 第八讲 · 分支与循环三 · 实现一个猜数字小游戏
    11.goto语句回顾一下几种控制语句C语⾔提供了⼀种⾮常特别的语法,就是goto语句和跳转标号,goto语句可以实现在同⼀个函数内跳转到设置好的标号处。goto语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以我们的建议是能不⽤尽量不去使⽤;但是g......
  • 二进制中1的个数(C语言)
    写一个函数返回参数二进制中1的个数(三种方法)主函数main的代码intmain(){ intnum=0; scanf("%d",&num); //接收1的个数 intn=count_num_of_1(num); printf("%d\n",n); return0;}方法一intcount_num_of_1(unsignedintn){ intcount=0; while......
  • C语言对各类复杂函数精确求导(在终端解析字符串并求导)
    目录为什么写?难点:对输入的任意函数字符串进行解析和计算具体用法: 直接在终端输入函数即可代码完成思路:第一步:定义数据结构第二步:解析表达式第三步:求导第四步:简化表达式第五步:求值第六步:写main函数代码实现:见下文代码结束:感谢阅读!BUG鸣谢:鸣谢为什么写?  ......
  • 使用win10 wsl子系统将 rust 程序静态编译为linux可执行文件
    chapterⅠ事情起因最近在学习rust,想把一部分java服务迁移至rust编写,但由于公司服务器都是linux系统,所以在找windows下交叉编译为linux可执行文件的方法,把bing首页搜索的结果试了个遍都不行,始终报错“musl-gcc”无法找到,搜遍全网都无法解决。最终在我不断尝试的过程中逐渐......
  • 实验6 C语言结构体、枚举应用编程
    实验6C语言结构体、枚举应用编程实验任务1——学生信息处理//P286例8.17//对教材示例代码作了微调,把输出学生信息单独编写成一个函数模块//打印不及格学生信息、打印所有学生信息均调用该模块实现#include<stdio.h>#include<string.h>#defineN3 //运行程序输入......
  • [C语言]指针篇
    一、什么是指针指针也叫内存地址。二、指针的格式三、指针的作用*是一个表示指针的符号,通过内存地址获取数据的意思。前面的*是一个标记,后面的*是查询地址。//利用指针去获取变量中的数据/存储数据inta=10;//1.定义一个指针去指向变量aint*p=&a;//2.......
  • Rust中用enum实现多参数Hook机制
    在Rust中,如果想为enum实现一个带多参数的Hook机制,可以结合模式匹配和枚举来处理。这种方式可以扩展到支持不同类型的输入参数和逻辑处理。以下是一个实现enum和Hook的多参数机制的完整示例:定义枚举和Hook类型usestd::sync::{Arc,Mutex};//定义一个多参......