grpc文件传输C++代码
时间: 2023-10-04 14:06:05 浏览: 190
以下是一个简单的使用 gRPC 进行文件传输的示例代码:
```cpp
// FileTransferService.proto
syntax = "proto3";
package filetransfer;
option csharp_namespace = "FileTransferService";
message FileRequest {
string file_name = 1;
}
message FileResponse {
bytes file_content = 1;
}
service FileTransfer {
rpc GetFile(FileRequest) returns (stream FileResponse);
}
```
```cpp
// FileTransferServiceClient.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <grpcpp/grpcpp.h>
#include "FileTransferService.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using filetransfer::FileRequest;
using filetransfer::FileResponse;
using filetransfer::FileTransfer;
class FileTransferServiceClient {
public:
FileTransferServiceClient(std::shared_ptr<Channel> channel) : stub_(FileTransfer::NewStub(channel)) {}
bool GetFile(const std::string& file_name, const std::string& output_file_path) {
FileRequest request;
request.set_file_name(file_name);
ClientContext context;
std::unique_ptr<grpc::ClientReader<FileResponse>> reader(stub_->GetFile(&context, request));
FileResponse response;
std::ofstream output_file(output_file_path, std::ios::binary);
if (!output_file.is_open()) {
std::cerr << "Failed to create output file: " << output_file_path << std::endl;
return false;
}
while (reader->Read(&response)) {
output_file.write(reinterpret_cast<char*>(response.file_content().data()), response.file_content().size());
}
const Status status = reader->Finish();
if (!status.ok()) {
std::cerr << "Failed to get file: " << status.error_code() << ": " << status.error_message() << std::endl;
return false;
}
return true;
}
private:
std::unique_ptr<FileTransfer::Stub> stub_;
};
int main(int argc, char** argv) {
const std::string server_address = "localhost:50051";
const std::string file_name = "example.txt";
const std::string output_file_path = "output.txt";
FileTransferServiceClient client(grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));
if (!client.GetFile(file_name, output_file_path)) {
std::cerr << "Failed to get file" << std::endl;
return 1;
}
return 0;
}
```
```cpp
// FileTransferServiceImpl.cpp
#include <fstream>
#include <grpcpp/grpcpp.h>
#include "FileTransferService.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using filetransfer::FileRequest;
using filetransfer::FileResponse;
using filetransfer::FileTransfer;
class FileTransferServiceImpl final : public FileTransfer::Service {
public:
Status GetFile(ServerContext* context, const FileRequest* request, grpc::ServerWriter<FileResponse>* writer) override {
const std::string file_name = request->file_name();
std::ifstream input_file(file_name, std::ios::binary);
if (!input_file.is_open()) {
return Status(grpc::StatusCode::NOT_FOUND, "File not found");
}
char buffer[1024];
while (input_file.good()) {
input_file.read(buffer, sizeof(buffer));
const int size = input_file.gcount();
if (size > 0) {
FileResponse response;
response.set_file_content(buffer, size);
writer->Write(response);
}
}
return Status::OK;
}
};
void RunServer() {
const std::string server_address = "0.0.0.0:50051";
FileTransferServiceImpl 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;
}
```
在此示例中,我们定义了一个名为 `FileRequest` 的 protocol buffer 消息,它包含一个文件名字段。然后,我们定义了一个名为 `FileResponse` 的协议缓冲区消息,它包含一个文件内容字段。最后,我们定义了一个名为 `FileTransfer` 的 gRPC 服务,它包含一个名为 `GetFile` 的方法,该方法接受一个 `FileRequest` 并返回一个 `stream FileResponse`。
客户端使用 `FileTransferServiceClient` 类来调用 `GetFile` 方法。该方法使用 `ClientReader` 类从服务器读取 `FileResponse` 流,并将响应写入一个输出文件中。
服务器使用 `FileTransferServiceImpl` 类来实现 `GetFile` 方法。该方法打开文件,然后将文件内容分块写入 `ServerWriter` 类中,以便客户端可以从流中读取响应。
阅读全文