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 ------------------------------------------------- ...
随机推荐
- Hdu4771(杭州赛区)
Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...
- 【CF706C】Hard problem
Description Vasiliy is fond of solving different tasks. Today he found one he wasn't able to solve h ...
- IDEA多模块父子依赖maven项目war包部署
IDEA多模块父子依赖maven项目war包部署 Posted on 2018-04-25 | In IDEA | | Visitors 286 IDEA全称为IntrlliJ IDEA,它是一款非常 ...
- spring mvc controller接收请求值及controller之间跳转及传值
spring接收请求参数: 1,使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(Ht ...
- 正則表達式基础及java使用
正則表達式基础 正則表達式语法(1) 普通字符:字母,数字.汉子,下划线以及没有特殊定义的标点符号都是"普通字符".表达式中的普通字符.在匹配一个字符串的时候,匹配与之同样 ...
- [经典面试题]k节点一组旋转链表
[题目] 给出一个链表和一个数k,比方链表1→2→3→4→5→6.k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4.翻转后4→3→2→1→5→6. 假设节点的数 ...
- 虚拟机的ip网络设置的选择
首先看一下vm的这几个设置 通过截图可以基本看到几个网络设置的区别,具体体现在虚拟机装好以后,网络设置会多出两个适配器,不同模式会分配不同区段的ip,需要固定时主要区段要求 所以总结一下 1.桥连,适 ...
- 对多线程java内存模型JMM
多线程概念的引入体现了人类重新有效压力寨计算机.这是非常有必要的,由于所涉及的读数据的过程中的一般操作,如从磁盘.其他系统.数据库等,CPU计算速度和数据读取速度已经严重失衡.假设印刷过程中一个线程将 ...
- Vue中this的绑定
之前写过一篇文章 ES6与React中this完全解惑 其实Vue也是相同的道理.在Vue的官方文档中提到: 不要在选项属性或回调上使用箭头函数,比如 created: () => consol ...
- 调试分析工具 (C/C++)
一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...