• 使用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 = 0; 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)/1000000 << 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 0; }

    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 0; }
  • 相关阅读:
    前端开发中一些好用的软件包。
    LeetCode 26 删除排序数组中的重复项
    算法 主定理
    算法学习计划继续三四个月
    Web Api
    DOM viewport
    CSS OM
    DOM Range Api
    DOM 操作 2
    DOM Event
  • 原文地址:https://www.cnblogs.com/xingmuxin/p/10738488.html
Copyright © 2020-2023  润新知