手写一个 RPC 远程调用(C++)

手写一个 RPC 远程调用(C++)

版权声明

个人作品,禁止转载

参考资料

  • Build Remote Procedure Calls (RPC) - from scratch in C(https://www.udemy.com/course/linuxrpc/)
  • Linux manual page(https://man7.org/linux/man-pages/)
  • Cpp reference(https://en.cppreference.com/w/)

代码下载

https://github.com/541380000/write_rpc_from_scratch.git
或者从网盘下载
链接:https://pan.baidu.com/s/1BjTK3aH_T80umXsF9Yzqmg?pwd=5mof
提取码:5mof

推荐进阶工具

  • protobuf(对象序列化工具,按字节序列化)
  • msgpack(对象序列化工具,类似 json,但更加精简)
  • Boost 的序列化库

Overview

  • 这是一个学习型项目,旨在学习 RPC 如何运行
  • 这是一个 C++项目,只是用 C++标准库,不使用第三方库
  • 各个步骤纯手写,代码无法用于商业项目
  • 本项目不考虑机器大小端

预备知识

  • 基础的 c/c++知识
  • 基础的 socket 编程
  • 基础的 debug 能力

RPC 的步骤

  • RPC 客户端,序列化 RPC 头和 RPC 参数
  • RPC 客户端,将 RPC 头和参数打包成数据包,通过网络(等其他通信手段)发送
  • RPC 服务器,反序列化 RPC 头和 RPC 参数
  • RPC 服务器,执行远程调用
  • RPC 服务器,将 RPC 头和返回值打包成数据包,发送给客户端
  • RPC 客户端,反序列化 RPC 头和返回值,得到 RPC 结果

序列化和反序列化

基础数据类型:SerBuffer

结构体定义
SerBuffer是数据序列化和反序列化的缓冲区
```
using byte=char;
struct SerBuffer{
    vector<byte> buffer;
};
```
方法
创建新的 SerBuffer,预留若干字节的空间
unique_ptr<SerBuffer> creatSerBuffer(const uint32_t buffer_size=DEFAULT_INIT_SERIALIZE_BUFFER_SIZE){
    auto ptr = make_unique<SerBuffer>();
    ptr->buffer.reserve(buffer_size);
    return move(ptr);
}
将 nBytes 的数据复制到 buffer 中
void serializeData(const unique_ptr<SerBuffer>& buffer, const byte* data, const uint32_t nBytes){
    copy(data, data+nBytes, back_inserter(buffer->buffer));
}
跳过 n 字节,nBytes 为负则从缓冲区删除数据,为正则追加 nBytes 个 0
void serializeBufferSkip(const unique_ptr<SerBuffer>& buffer, int32_t nBytes){
    if (nBytes < 0)
        while(nBytes < 0) buffer->buffer.pop_back(), nBytes ++;
    else if (nBytes > 0)
        while(nBytes > 0) buffer->buffer.emplace_back('0'), nBytes --;
}
清空缓冲区
void resetSerBuffer(const unique_ptr<SerBuffer>& buffer){
    buffer->buffer.clear();
}
填充一个空指针,空指针用 0xFFFFFFFF 表示
void fillNull(const unique_ptr<SerBuffer>& buffer){
    uint32_t sentinel = 0xFFFFFFFF;
    serializeData(buffer, (byte*)&sentinel, 4);
}
将 RPC 头序列化到 buffer 中(RPC 头定义见下文)
void serializeRPCHeader(const unique_ptr<SerBuffer>& buffer, const RPCHeader* const header){
    serializeData(buffer, (char*)header, sizeof(header));
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值