使用c++如何实现在gRPC中传输文件
使用c++实现gRPC远程调用框架中传输文件,proto文件如下:
syntax = "proto3";
package transferfile;
service TransferFile {
rpc Upload(stream Chunk) returns (Reply) {}
}
message Chunk {
bytes buffer = 1;
}
message Reply {
int32 length = 1;
}
对应的c++代码如下:
client端:
#include <iostream>
#include <string>
#include <fstream>
#include <sys/time.h>
#include <grpc/grpc.h>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/security/credentials.h>
#include "transfer_file.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::ClientWriter;
using grpc::Status;
using transferfile::Chunk;
using transferfile::Reply;
using transferfile::TransferFile;
#define CHUNK_SIZE 1024 * 1024
class TransferFileClient
{
public:
TransferFileClient(std::shared_ptr<Channel> channel) : stub_(TransferFile::NewStub(channel)){};
void Upload();
private:
std::unique_ptr<TransferFile::Stub> stub_;
}; void TransferFileClient::Upload()
{
Chunk chunk;
char data[CHUNK_SIZE];
Reply stats;
ClientContext context;
const char *filename = "./large_file_in";
std::ifstream infile;
int len = ;
struct timeval start, end; gettimeofday(&start, NULL);
infile.open(filename, std::ifstream::in | std::ifstream::binary);
std::unique_ptr<ClientWriter<Chunk>> writer(stub_->Upload(&context, &stats));
while (!infile.eof()) {
infile.read(data, CHUNK_SIZE);
chunk.set_buffer(data, infile.gcount());
if (!writer->Write(chunk)) {
// Broken stream.
break;
}
len += infile.gcount();
}
writer->WritesDone();
Status status = writer->Finish();
if (status.ok()) {
gettimeofday(&end, NULL);
std::cout << (end.tv_sec-start.tv_sec)+ (double)(end.tv_usec-start.tv_usec)/ << std::endl;
} else {
std::cout << "TransferFile rpc failed." << std::endl;
}
}
int main(int argc, char** argv){
TransferFileClient guide(grpc::CreateChannel("localhost:10000", grpc::InsecureChannelCredentials()));
guide.Upload();
return ;
}
server端:
#include <iostream>
#include <fstream>
#include <string>
#include <grpc/grpc.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/security/server_credentials.h>
#include "transfer_file.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerReader;
using grpc::Status;
using transferfile::Chunk;
using transferfile::Reply;
using transferfile::TransferFile;
#define CHUNK_SIZE 1024 * 1024 class TransferFileImpl final : public TransferFile::Service {
public:
Status Upload(ServerContext* context, ServerReader<Chunk>* reader, Reply* reply);
}; Status TransferFileImpl::Upload(ServerContext* context, ServerReader<Chunk>* reader, Reply* reply) {
Chunk chunk;
const char *filename = "./server_tmp";
std::ofstream outfile;
const char *data;
outfile.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
while (reader->Read(&chunk)) {
data = chunk.buffer().c_str();
outfile.write(data, chunk.buffer().length());
}
long pos = outfile.tellp();
reply->set_length(pos);
outfile.close();
return Status::OK;
} void RunServer() {
std::string server_address("0.0.0.0:50051");
TransferFileImpl 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(int argc, char** argv) {
RunServer();
return ;
}
使用c++如何实现在gRPC中传输文件的更多相关文章
- Linux学习系列--如何在Linux中进行文件的管理
文件 在常见的Linux的文件系统中,经常使用能了解到的文件管理系统是分为多个文件夹进行管理的. 如何查看文件路径 pwd ,在文件目录中,会有一个点(.)代表的是当前目录,两个点(..)代表的是当前 ...
- grpc中的拦截器
0.1.索引 https://waterflow.link/articles/1665853719750 当我们编写 HTTP 应用程序时,您可以使用 HTTP 中间件包装特定于路由的应用程序处理程序 ...
- linux命令(28):Linux下SCP无需输入密码传输文件,python 中scp文件
python 中scp文件:(如果下面的发送免密码已经完成的话,就直接能用下面这个) os.system('scp "%s" "%s:%s"' % (" ...
- 工具WinSCP:windows和Linux中进行文件传输
工具WinSCP:windows和Linux中进行文件传输 2016-09-21 [转自]使用WinSCP软件在windows和Linux中进行文件传输 当我们的开发机是Windows,服务器是Lin ...
- Linux中常用文件传输命令及使用方法
sftp sftp即Secure Ftp 是一个基于SSH安全协议的文件传输管理工具.由于它是基于SSH的,会在传输过程中对用户的密码.数据等敏感信息进行加密,因此可以有效的防止用户信息在传输的过程中 ...
- 【转】参照protobuf,将json数据转换成二进制在网络中传输。
http://blog.csdn.net/gamesofsailing/article/details/38335753?utm_source=tuicool&utm_medium=refer ...
- 用WPF实现在ListView中的鼠标悬停Tooltip显示
原文:用WPF实现在ListView中的鼠标悬停Tooltip显示 一.具体需求描述 在WPF下实现,当鼠标悬停在ListView中的某一元素的时候能弹出一个ToolTip以显示需要的信息. 二.代码 ...
- 使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部
使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部 <template> <div> <table> <tr v-for="i ...
- PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。
PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...
随机推荐
- 在dotnet core下去中心化访问HTTP服务集群
一般应用服务都会部署到多台服务器之上,一.可以通过硬件得到更多的并发处理能力:二.可以避免单点太故障的出现,从而确保服务7X24有效运作.当访问这些HTTP服务的情况一般都是经过反向代理服务进行统一处 ...
- TypeScript 中非代码模块的导入
需要理解的是,TypeScript 作为语言,他只处理代码模块.其他类型的文件这种非代码模块的导入,讲道理是通过另外的打包工具来完成的,比如 Web 应用中的图片,样式,JSON 还有 HTML 模板 ...
- 补习系列(17)-springboot mongodb 内嵌数据库
目录 简介 一.使用 flapdoodle.embed.mongo A. 引入依赖 B. 准备测试类 C. 完善配置 D. 启动测试 细节 二.使用Fongo A. 引入框架 B. 准备测试类 C.业 ...
- Vue Mixin 与微信小程序 Mixins 应用
什么是Mixin(混入) Mixin是一种思想,用来实现代码高度可复用性,可以针对属性复制实现代码复用的想法进行一个扩展,就是混入(mixin).混入并不是复制一个完整的对象,而是从多个对象中复制出任 ...
- 获得当前EIP的值
VS2017 内联汇编 __asm { call NEXT NEXT: pop eax }
- Python编程从入门到实践笔记——操作列表
Python编程从入门到实践笔记——操作列表 #coding=utf-8 magicians = ['alice','david','carolina'] #遍历整个列表 for magician i ...
- jQuery获取或设置元素的宽度和高度
jQuery获取或设置元素的宽度和高度: 可使用以下3种方法: 1,jQuery width() 和 height() 方法: 2,innerWidth() 和 innerHeight() 方法: 3 ...
- Java多线程知识整理
多线程 1. 多线程基础 多线程状态转换图 普通方法介绍 yeild yeild,线程让步.是当前线程执行完后所有线程又统一回到同一起跑线.让自己或者其他线程运行,并不是单纯的让给其他线程. join ...
- vmware完整克隆(linux)
vmware中的完整克隆是基于指定的虚拟机克隆出相同的一份出来,不必再安装 但是我们要保证三个地方不能一样,一个是主机名称(hostname),一个是虚拟网卡设备mac地址,还有一个是ip地址 所以我 ...
- 一起学Android之ProgressBar
本文简述在Android开发中进度条(ProgressBar)的常见应用,仅供学习分享使用. 概述 在Android开发中,进度条的使用场景有很多,如播放电影时可拖动的观看进度条,评分时使用的评分条, ...