目前已经全部完成,并且取得了非常好的效果 。
使用 febird.RPC 的一个文件服务器代码:
// ifile.h class FileObj : public SessionScope { public: BEGIN_RPC_ADD_MF(FileObj) RPC_ADD_MF(open) RPC_ADD_MF(read) RPC_ADD_MF(write) RPC_ADD_MF(close) END_RPC_ADD_MF() RPC_DECLARE_MF(open, (const std::string& fname, const std::string& mode)) RPC_DECLARE_MF(read, (vector<byte>* buffer, uint32_t length)) RPC_DECLARE_MF(write, (const vector<byte>& buffer, uint32_t* length)) RPC_DECLARE_MF(close, ()) }; RPC_TYPEDEF_PTR(FileObj);
// file_client.cpp #include <stdio.h> #include <febird/rpc/client.h> #include <febird/io/SocketStream.h> using namespace std; using namespace febird; using namespace febird::rpc; #include "../ifile.h" int main(int argc, char** argv[]) { #ifdef _WIN32 WSADATA information; WSAStartup(MAKEWORD(2, 2), &information); #endif try { auto_ptr<SocketStream> cs(ConnectSocket("127.0.0.1:8001")); rpc_client<PortableDataInput, PortableDataOutput> client(cs.get()); FileObjPtr file; client.create(file); string fname = "test.txt"; vector<byte> buffer; int ret = file->open(fname, "w+"); if (0 == ret) { printf("open file for write successed\n"); string txt = "Hello, world, this is a test file\n"; buffer.resize(txt.size()); std::copy(txt.begin(), txt.end(), buffer.begin()); uint32_t nWritten; file->write(buffer, &nWritten); printf("write=%d, written=%d\n", buffer.size(), nWritten); file->close(); } ret = file->open("test.txt", "r"); if (0 == ret) { printf("open file for read successed\n"); uint32_t nRead = buffer.size(); file->read(&buffer, nRead); printf("read=%d, readed=%d\n", nRead, buffer.size()); string txt; txt.resize(buffer.size()); std::copy(buffer.begin(), buffer.end(), txt.begin()); printf("readed text=%s\n", txt.c_str()); } else { printf("open file for read failed\n"); } } catch (const std::exception& exp) { printf("exception: what=%s\n", exp.what()); } #ifdef _WIN32 WSACleanup(); #endif return 0; }
// file_server.cpp #include <stdio.h> #include <febird/rpc/server.h> #include <febird/io/SocketStream.h> #include <iostream> using namespace std; using namespace febird; using namespace febird::rpc; #include "../ifile.h" BEGIN_RPC_IMP_INTERFACE(FileObjImp, FileObj) FileObjImp() { fp = 0; } ~FileObjImp() { if (fp) { fclose(fp); } } rpc_return_t open(const std::string& fname, const std::string& mode) { fp = fopen(fname.c_str(), mode.c_str()); if (0 == fp) return errno; return 0; } rpc_return_t read(vector<byte>* buffer, uint32_t length) { buffer->resize(length); size_t nRead = fread(&*buffer->begin(), 1, length, fp); buffer->resize(nRead); return 0; } rpc_return_t write(const vector<byte>& buffer, uint32_t* length) { *length = fwrite(&*buffer.begin(), 1, buffer.size(), fp); return 0; } rpc_return_t FileObj::close() { fclose(fp); fp = 0; return 0; } private: FILE* fp; END_RPC_IMP_INTERFACE() int main(int argc, char** argv[]) { #ifdef _WIN32 WSADATA information; WSAStartup(MAKEWORD(2, 2), &information); #endif try { SocketAcceptor acceptor("0.0.0.0:8001"); rpc_server<PortableDataInput, PortableDataOutput> server(&acceptor); // FileObjImp will auto created by client call RPC_SERVER_AUTO_CREATE(server, FileObjImp); server.start(); } catch (const std::exception& exp) { printf("exception: what=%s\n", exp.what()); } #ifdef _WIN32 WSACleanup(); #endif return 0; }