-
Notifications
You must be signed in to change notification settings - Fork 1
/
file_client.cc
106 lines (89 loc) · 3 KB
/
file_client.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <string>
#include <fstream>
#include <grpcpp/grpcpp.h>
#include "file.grpc.pb.h"
#define defaultbuffersize 4096 // suggested size by https://stackoverflow.com/questions/3033771/file-i-o-with-streams-best-memory-buffer-size
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::ClientWriter;
using file::FileRequest;
using file::FileReply;
using file::File;
class FileClient {
public:
FileClient(std::shared_ptr<Channel> channel)
: stub_(File::NewStub(channel)) {}
void UploadFile(const std::string& filepath,const std::string& str,const long num,const int buffersize){
FileReply reply;
ClientContext context;
char * memblock;
//open file and prepare meta data
int fileByte;
std::ifstream f (filepath, std::ios::in|std::ios::binary|std::ios::ate);
if (f.is_open()){
fileByte = f.tellg();
}else{
std::cout << "client:\t\t Unable to open file trying to upload";
std::exit(-1);
}
context.AddMetadata("f_str",str);
context.AddMetadata("f_num",std::to_string(num));
context.AddMetadata("f_byte",std::to_string(fileByte));
context.AddMetadata("f_buffer",std::to_string(buffersize));
// file stream start
memblock = new char [buffersize];
f.seekg (0, std::ios::beg);
std::unique_ptr<ClientWriter<FileRequest> > writer(stub_->UploadFile(&context, &reply));
int size=buffersize;
while (f){
f.read(memblock, buffersize);
if(f.eof()){
//adjust "content" size for the last steam, it may be smaller than the buffer size
size=fileByte%buffersize;
}
FileRequest request;
//NEED SIZE. Without size, if char* contain 0x00, it will be treated as EOF, cause incomplete byte transfer
std::string s(memblock, size);
request.set_content(s);
if(!writer->Write(request)){
break;
}
}
delete[] memblock;
//stream done
writer->WritesDone();
Status status = writer->Finish();
//waiting server to reply
if (status.ok()) {
std::cout << "client:\t\t replay message: "<<reply.message() << '\n';
}else{
std::cout <<"client:\t\t "<< status.error_code() << ": " << status.error_message();
std::cout << "client:\t\t file rpc failed." << std::endl;
}
}
private:
std::unique_ptr<File::Stub> stub_;
};
int main(int argc, char** argv) {
// --help
if(argc<4 || argc>5 ){
std::cout << "client:\t\t missing arguement.\n------ need file path, string, number, [optional buffersize]" << '\n';
return -1;
}
//get arguement
std::string path=argv[1];
std::string str=argv[2];
long num=std::stol(argv[3]);
//connect to server for upload
FileClient file(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
if(argc==4){
//when arg does not conatin buffer size
file.UploadFile(path,str,num,defaultbuffersize);
}else{
//when arg conatin buffer size
file.UploadFile(path,str,num,std::stoi(argv[4]));
}
return 0;
}