RPC协议及库介绍
一.RPC介绍
RPC(Remote Procedure Call),远程过程调用协议,客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样,即允许像调用本地服务一样调用远程服务。
RPC框架的目的就是让远程服务调用更简单、透明,由RPC框架负责屏蔽底层的序列化、传输方式和通信细节,开发者在使用时只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。
二.libsunrpc协议库
1.libsunrpc(Sun Remote Procedure Call Library)是 Unix/Linux 系统上实现 RPC(远程过程调用)的基础库,基于 Sun Microsystems 开发的经典 RPC 协议。它为 C/C++ 开发者提供了跨主机调用函数的能力,
是 NFS(网络文件系统)、NIS(网络信息服务)等核心服务的底层通信基础。
2.协议基础
基于 TCP/UDP:支持两种传输层协议,默认使用 UDP(适合小数据量快速请求)。
XDR 序列化:使用外部数据表示(External Data Representation, XDR)进行数据编码,确保跨平台数据格式一致性。
RPC 协议:实现标准 RPC 协议(RFC 1057),包括过程编号、消息格式和错误处理。
3.API 设计
C 语言接口:提供简洁的函数式 API,包括客户端调用和服务器实现。
自动生成工具:通过 rpcgen 工具从 IDL(接口定义语言)文件生成客户端 / 服务器代码。
异步支持:支持非阻塞调用和回调机制。
4.系统集成
Unix/Linux 原生支持:几乎所有 Linux 发行版默认安装,无需额外依赖。
与系统服务集成:是 NFS、NIS、ypbind 等系统服务的基础库。
5.开发流程
(1)定义服务接口(.x 文件):
// example.x
program EXAMPLE_PROG {
version EXAMPLE_VERS {
int ADD(int, int) = 1;
int SUB(int, int) = 2;
} = 1;
} = 0x20000001; // 唯一程序编号
(2)生成代码:
rpcgen example.x # 生成 example_clnt.c, example_svc.c, example_xdr.c
(3)实现服务端:
// 服务实现
#include "example.h"
int *add_1_svc(int *argp, struct svc_req *rqstp) {
static int result;
result = argp[0] + argp[1];
return &result;
}
int main() {
registerrpc(EXAMPLE_PROG, EXAMPLE_VERS, ADD_1, add_1_svc, IPPROTO_UDP);
svc_run(); // 进入无限循环处理请求
return 0;
}
(4)实现客户端:
#include "example.h"
int main() {
CLIENT *clnt;
int *result;
int a = 5, b = 3;
clnt = clnt_create("server_host", EXAMPLE_PROG, EXAMPLE_VERS, "udp");
if (clnt == NULL) {
clnt_pcreateerror("server_host");
return 1;
}
result = add_1(&a, &b, clnt);
if (result == NULL) {
clnt_perror(clnt, "call failed");
} else {
printf("加法结果: %d\n", *result);
}
clnt_destroy(clnt);
return 0;
}
6.典型应用场景
系统服务通信
NFS(网络文件系统)通过 RPC 实现跨主机文件访问。
NIS(网络信息服务)用于集中管理用户账号和系统配置。
分布式应用
集群环境中节点间的函数调用(如分布式计算框架)。
嵌入式系统
资源受限设备间的轻量级通信(需注意 UDP 可靠性)。
三.对比其他 RPC 库