Linux下C语言RPC(远程过程调用)编程实例
在查看libc6-dev软件包提供的工具(用 dpkg -L libc6-dev 命令)的时候,发现此软件包提供了一个有用的工具rpcgen命令。
通过rpcgen的man手册看到此工具的作用是把RPC源程序编译成C语言源程序,从而轻松实现远程过程调用。
下面的例子程序的作用是客户端程序取中心服务器上时间的,编程过程如下:
先编写一个 “ RPC 语言 ” ( RPC Language ( Remote Procedure Call Language ) ) 的源文件 test.x ,文件后缀名为 x 。
源代码如下:
| program TESTPROG { version VERSION { string TEST(string) = 1; } = 1; } = 87654321; |
说明:这里数字87654321是RPC程序编号,还有VERSION版本号为1,都是给RPC服务程序用的。同时指定程序接受一个字符串参数。
运行这个命令:
| rpcgen test.x |
将生成三个源文件:
| test_clnt.c test.h test_svc.c |
源文件test_clnt.c 内容如下:
| /* * Please do not edit this file. * It was generated using rpcgen. */ #include <memory.h> /* for memset */ /* Default timeout can be changed using clnt_control() */ char ** memset((char *)&clnt_res, 0, sizeof(clnt_res)); |
说明:这是一个客户端调用函数,即客户端代码需要用到此函数。
源文件test.h内容如下:
| /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _TEST_H_RPCGEN #include <rpc/rpc.h> #ifdef __cplusplus #define TESTPROG 87654321 #if defined(__STDC__) || defined(__cplusplus) #else /* K&R C */ #ifdef __cplusplus #endif /* !_TEST_H_RPCGEN */ |
说明:这里定义了一些公用头文件。
源文件test_svc.c内容如下:
| /* * Please do not edit this file. * It was generated using rpcgen. */ #include "test.h" #ifndef SIG_PF static void switch (rqstp- case NULLPROC: case TEST: default: int pmap_unset (TESTPROG, VERSION); transp = svcudp_create(RPC_ANYSOCK); transp = svctcp_create(RPC_ANYSOCK, 0, 0); svc_run (); |
说明:这是一个标准的服务器端代码。
运行下列命令生成一个客户端源文件test_client.c:
| rpcgen -Sc -o test_client.c test.x |
源代码test_client.c如下:
| /* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "test.h" void #ifndef DEBUG result_1 = test_1(&test_1_arg, clnt); int if (argc > 2) { |
运行这个命令生成服务端源文件test_srv_func.c:
| rpcgen -Ss -o test_srv_func.c test.x |
源文件test_srv_func.c内容如下:
| /* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "test.h" char ** /* return &result; |
说明:这是一个服务器端调用的函数。
至此,我们就可以编译生成程序来运行了。
用下面的命令编译生成服务端程序test_server:
| gcc -Wall -o test_server test_clnt.c test_srv_func.c test_svc.c |
用下面的命令编译生成客户端程序test_client:
| gcc -Wall -o test_client test_client.c test_clnt.c |
运行下列命令启动服务端:
| ./test_server |
运行下列命令可以进行客户端测试:
| ./test_client 127.0.0.1 |
但是由于现的的服务端没有处理客户端请求,所以这样的程序还不能完成任何工作。
下面我们先给服务端程序加上代码,使这个服务器能完成一定的工作。即修改 test_srv_func.c ,在 “ * insert server code here ” 后面加上取时间的代码,即修改后的 test_srv_func.c 代码如下:
| /* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include <time.h> #include "test.h" char ** /* return &result; |
再修改客户端代码以显示服务器端返回的内容,即修改test_client.c源文件,只需要修改其中的函数testprog_1,修改后如下:
| void testprog_1(char *host) { CLIENT *clnt; char * *result_1; char * test_1_arg; test_1_arg = (char *)malloc(128); result_1 = test_1(&test_1_arg, clnt); |
重新运行上述编译命令编译生成程序:
| gcc -Wall -o test_server test_clnt.c test_srv_func.c test_svc.c gcc -Wall -o test_client test_client.c test_clnt.c |
启动服务端程序后运行客户端程序如下:
| ./test_client 127.0.0.1 收到消息 ... 服务器当前时间是 :Tue Feb 27 11:45:21 2007 |
为了省略每次输入gcc命令的麻烦,也为了维护我们的工程,可以运行下列命令生成一个Makefile文件:
| rpcgen -Sm test.x > Makefile |
生成的Makefile内容如下:
| # This is a template Makefile generated by rpcgen
# Parameters CLIENT = test_client SOURCES_CLNT.c = TARGETS_SVC.c = OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) CFLAGS += -g # Targets all : $(CLIENT) $(SERVER) $(TARGETS) : $(SOURCES.x) $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) $(CLIENT) : $(OBJECTS_CLNT) $(SERVER) : $(OBJECTS_SVC) clean: |
由于我们手工生成了源文件,所以要修改一下这个Makefile,修改后如下:
| # This is a template Makefile generated by rpcgen
# Parameters CLIENT = test_client SOURCES_CLNT.c = TARGETS_SVC.c = test_clnt.c test_srv_func.c test_svc.c OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) CFLAGS += -g # Targets all : $(CLIENT) $(SERVER) $(TARGETS) : $(SOURCES.x) $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) $(CLIENT) : $(OBJECTS_CLNT) $(SERVER) : $(OBJECTS_SVC) clean: |
转自:http://blog.csdn.net/hitxiaotao/article/details/2267523
http://blog.csdn.net/iw1210/article/details/41051779
Linux下C语言RPC(远程过程调用)编程实例的更多相关文章
- Linux下C语言的socket网络编程
关于详细的服务器建立的步骤以及相关的socket套接字的知识我已经在python socket编程的文章中提到过了,大家可以参看那一篇博客来历接socket套接字编程的内容,由于要是用C相关的API所 ...
- Linux下C语言的进程控制编程
代码: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/ty ...
- Linux下C语言编程实现spwd函数
Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...
- Linux基础与Linux下C语言编程基础
Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- LINUX下C语言编程调用函数、链接头文件以及库文件
LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...
- linux下C语言多线程编程实例
用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...
- Linux下C语言编程基础学习记录
VIM的基本使用 LINUX下C语言编程 用gcc命令编译运行C语言文件 预处理阶段:将*.c文件转化为*.i预处理过的C程序. 编译阶段:将*.i文件编译为汇编代码*.s文件. 汇编阶段:将*.s ...
- 【转】Linux基础与Linux下C语言编程基础
原文:https://www.cnblogs.com/huyufeng/p/4841232.html ------------------------------------------------- ...
随机推荐
- [ExtJS5学习笔记]第九节 Extjs5的mvc与mvvm框架结构简单介绍
本文地址:http://blog.csdn.net/sushengmiyan/article/details/38537431 本文作者:sushengmiyan ------------------ ...
- ssh连接上腾讯云、华为云Linux服务器,一会就自动断开
客户端向服务端发送心跳 依赖 ssh 客户端定时发送心跳,putty.SecureCRT.XShell 都有这个功能. Linux / Unix 下,编辑 ssh 配置文件: # vim /etc/s ...
- html常用属性border-radius、linear-gradient怎么使用
html常用属性border-radius.linear-gradient怎么使用 一.总结 一句话总结: 1.border-radius: 8px 8px 8px 8px !important; 2 ...
- 【NOIP2012提高组】国王游戏 贪心 + 高精度
题目分析 题目答案不具有单调性,所以不可以二分,转而思考贪心.因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优.若设对于位置$i$,$a[ ...
- Ultra-wideband (UWB) secure wireless device pairing and associated systems
Methods and systems are disclosed for ultra-wideband (UWB) secure wireless device pairing. Secure pa ...
- jQuery立即调用表达式
http://www.imooc.com/code/3247 立即调用表达式 任何库与框架设计的第一个要点就是解决命名空间与变量污染的问题.jQuery就是利用了JavaScript函数作用域的特性, ...
- 详尽分析世纪之战:360VS腾讯是两个阶层的抗争
很不错的一篇文字 分析的也很透彻 [转自中国移动http://labs.chinamobile.com/] 来源:搜狐IT 作者:吃熊掌的鱼 2010-11-01 10:11:51 [ 13967阅 ...
- Qt::WindowFlags枚举类型(Qt::Widget是独立窗口和子窗口两用的,Qt::Window会有标题栏)
Qt::Widget : QWidget构造函数的默认值,如新的窗口部件没有父窗口部件,则它是一个独立的窗口,否则就是一个子窗口部件. Qt::Window : 无论是否有父窗口部件,新窗口部件都是一 ...
- Qt图片自适应窗口控件大小(使用setScaledContents)
最近在用Qt设计一个小程序,想让一幅图片自适应窗口大小,由于本人比较笨,一直找不到好方法.找到了很多方法但都会出一些小问题, 刚刚摸索出解决办法了,在些记录. 思想: 1 显示图像是用QLabel2 ...
- robot framework的使用说明
robot framework安装说明1.安装python2.7.15运行安装包python-2.7.15.amd64.msi 2.robot framework(1)解压最新的压缩包如robotfr ...