使用c++实现gRPC远程调用框架中传输文件,proto文件如下:

  1. syntax = "proto3";
  2. package transferfile;
  3. service TransferFile {
  4. rpc Upload(stream Chunk) returns (Reply) {}
  5. }
  6. message Chunk {
  7. bytes buffer = 1;
  8. }
  9. message Reply {
  10. int32 length = 1;
  11. }

对应的c++代码如下:

client端:

  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. #include <sys/time.h>
  5. #include <grpc/grpc.h>
  6. #include <grpc++/channel.h>
  7. #include <grpc++/client_context.h>
  8. #include <grpc++/create_channel.h>
  9. #include <grpc++/security/credentials.h>
  10. #include "transfer_file.grpc.pb.h"
  11. using grpc::Channel;
  12. using grpc::ClientContext;
  13. using grpc::ClientWriter;
  14. using grpc::Status;
  15. using transferfile::Chunk;
  16. using transferfile::Reply;
  17. using transferfile::TransferFile;
  18. #define CHUNK_SIZE 1024 * 1024
  19. class TransferFileClient
  20. {
  21. public:
  22. TransferFileClient(std::shared_ptr<Channel> channel) : stub_(TransferFile::NewStub(channel)){};
  23. void Upload();
    private:
  24. std::unique_ptr<TransferFile::Stub> stub_;
  25. };
  26.  
  27. void TransferFileClient::Upload()
  28. {
  29. Chunk chunk;
  30. char data[CHUNK_SIZE];
  31. Reply stats;
  32. ClientContext context;
  33. const char *filename = "./large_file_in";
  34. std::ifstream infile;
  35. int len = ;
  36. struct timeval start, end;
  37.  
  38. gettimeofday(&start, NULL);
  39. infile.open(filename, std::ifstream::in | std::ifstream::binary);
  40. std::unique_ptr<ClientWriter<Chunk>> writer(stub_->Upload(&context, &stats));
  41. while (!infile.eof()) {
  42. infile.read(data, CHUNK_SIZE);
  43. chunk.set_buffer(data, infile.gcount());
  44. if (!writer->Write(chunk)) {
  45. // Broken stream.
  46. break;
  47. }
  48. len += infile.gcount();
  49. }
  50. writer->WritesDone();
  51. Status status = writer->Finish();
  52. if (status.ok()) {
  53. gettimeofday(&end, NULL);
  54. std::cout << (end.tv_sec-start.tv_sec)+ (double)(end.tv_usec-start.tv_usec)/ << std::endl;
  55. } else {
  56. std::cout << "TransferFile rpc failed." << std::endl;
  57. }
  58. }
  59. int main(int argc, char** argv){
  60. TransferFileClient guide(grpc::CreateChannel("localhost:10000", grpc::InsecureChannelCredentials()));
  61. guide.Upload();
  62. return ;
  63. }

server端:

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <grpc/grpc.h>
  5. #include <grpc++/server.h>
  6. #include <grpc++/server_builder.h>
  7. #include <grpc++/server_context.h>
  8. #include <grpc++/security/server_credentials.h>
  9. #include "transfer_file.grpc.pb.h"
  10. using grpc::Server;
  11. using grpc::ServerBuilder;
  12. using grpc::ServerContext;
  13. using grpc::ServerReader;
  14. using grpc::Status;
  15. using transferfile::Chunk;
  16. using transferfile::Reply;
  17. using transferfile::TransferFile;
  18. #define CHUNK_SIZE 1024 * 1024
  19.  
  20. class TransferFileImpl final : public TransferFile::Service {
  21. public:
  22. Status Upload(ServerContext* context, ServerReader<Chunk>* reader, Reply* reply);
  23. };
  24.  
  25. Status TransferFileImpl::Upload(ServerContext* context, ServerReader<Chunk>* reader, Reply* reply) {
  26. Chunk chunk;
  27. const char *filename = "./server_tmp";
  28. std::ofstream outfile;
  29. const char *data;
  30. outfile.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
  31. while (reader->Read(&chunk)) {
  32. data = chunk.buffer().c_str();
  33. outfile.write(data, chunk.buffer().length());
  34. }
  35. long pos = outfile.tellp();
  36. reply->set_length(pos);
  37. outfile.close();
  38. return Status::OK;
  39. }
  40.  
  41. void RunServer() {
  42. std::string server_address("0.0.0.0:50051");
  43. TransferFileImpl service;
  44. ServerBuilder builder;
  45. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  46. builder.RegisterService(&service);
  47. std::unique_ptr<Server> server(builder.BuildAndStart());
  48. std::cout << "Server listening on " << server_address << std::endl;
  49. server->Wait();
  50. }
  51.  
  52. int main(int argc, char** argv) {
  53. RunServer();
  54. return ;
  55. }

使用c++如何实现在gRPC中传输文件的更多相关文章

  1. Linux学习系列--如何在Linux中进行文件的管理

    文件 在常见的Linux的文件系统中,经常使用能了解到的文件管理系统是分为多个文件夹进行管理的. 如何查看文件路径 pwd ,在文件目录中,会有一个点(.)代表的是当前目录,两个点(..)代表的是当前 ...

  2. grpc中的拦截器

    0.1.索引 https://waterflow.link/articles/1665853719750 当我们编写 HTTP 应用程序时,您可以使用 HTTP 中间件包装特定于路由的应用程序处理程序 ...

  3. linux命令(28):Linux下SCP无需输入密码传输文件,python 中scp文件

    python 中scp文件:(如果下面的发送免密码已经完成的话,就直接能用下面这个) os.system('scp "%s" "%s:%s"' % (" ...

  4. 工具WinSCP:windows和Linux中进行文件传输

    工具WinSCP:windows和Linux中进行文件传输 2016-09-21 [转自]使用WinSCP软件在windows和Linux中进行文件传输 当我们的开发机是Windows,服务器是Lin ...

  5. Linux中常用文件传输命令及使用方法

    sftp sftp即Secure Ftp 是一个基于SSH安全协议的文件传输管理工具.由于它是基于SSH的,会在传输过程中对用户的密码.数据等敏感信息进行加密,因此可以有效的防止用户信息在传输的过程中 ...

  6. 【转】参照protobuf,将json数据转换成二进制在网络中传输。

    http://blog.csdn.net/gamesofsailing/article/details/38335753?utm_source=tuicool&utm_medium=refer ...

  7. 用WPF实现在ListView中的鼠标悬停Tooltip显示

    原文:用WPF实现在ListView中的鼠标悬停Tooltip显示 一.具体需求描述 在WPF下实现,当鼠标悬停在ListView中的某一元素的时候能弹出一个ToolTip以显示需要的信息. 二.代码 ...

  8. 使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部

    使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部 <template> <div> <table> <tr v-for="i ...

  9. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

随机推荐

  1. java~lambda表达式让查询更优雅

    在java之前的版本里,如果希望从集合时查找符合条件的数据,如果先遍历他,这种写法是我们不能接受的,所以现在java有了lambda就很好的解决了这个问题,让代码更优雅一些! /** * lambda ...

  2. 全文检索-Elasticsearch (四) elasticsearch.net 客户端

    本篇摘自elasticsearch.net search入门使用指南中文版(翻译) 原文:http://edu.dmeiyang.com/book/nestusing.html elasticsear ...

  3. 解决在C#(.net)按字节数截取字符串最后出现乱码的问题

    最近需要用到按字节数截取字符串.在网上找了很多方法. Encoding.Default.GetString采用的DefaultEncoding.UTF8.GetBytes采用的是utf-8编码.这样当 ...

  4. 【开源分享】2018CRM C# 源码(基于小黄豆CRMv2.0.925.3版本功能更新)

    分享出来的初衷,我分享一下最近我在小黄豆CRM2.0版本(小黄豆CRM+v2.0.925.3)上加的功能,如果有类似需求的,可以把功能代码发你,节约你的开发时间.(这是在小黄豆开源免费CRM①群231 ...

  5. OSS上传文件到阿里云

    最近做项目,需要上传文件,因为上传到项目路径下,感觉有时候也挺不方便的,就试了一下上传文件到阿里云oss上去了, oss的使用网上有很多介绍,都是去配置一下需要的数据,然后直接调用他的api就可以了. ...

  6. mysql入门知识

    数据库 什么是数据库就是存储数据的仓库(容器) 存储数据的方式1.变量 无法永久存储2.文件处理 ,可以永久存储 文件处理存在的弊端: 1.文件处理速度慢 2.文件只能在自己的计算机上读写 无法被共享 ...

  7. new会返回NULL空指针吗

    c++中的new会返回NULL空指针吗 https://stackoverflow.com/questions/3389420/will-new-operator-return-null On a s ...

  8. 【English】十、"谓语的地方"看到有两个动词:I go say hello.、非谓语形式

    一.I go say hello. 这是一种偏口语的说法.一个句子中不能同时有两个谓语. 标准的用法有: I go and say hello. and 连接这两个动词,表示并列等关系.go and ...

  9. Windows中通过命令行启动打开Service 管理工具

    经常需要打开Services 管理工具操控Service 的启动,停止. 通过控制面板 --> 管理工具 -->Service  太慢. 学到一个快捷方式. windows + R  启动 ...

  10. python3 购物车 增改查终极版~

    还是先来条NLP再说,快没了,以后想抄还没有... 十一,没有挫败,只有回应讯息 “挫败”只是指出过去的做法得不到预期的效果,是给我们需要改变的信号. “挫败”只是在事情画上句号时才能用上,欲想事情解 ...