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 ------------------------------------------------- ...
随机推荐
- 【codeforces 760C】Pavel and barbecue
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 后台报错java.lang.IllegalArgumentException: Invalid character found in the request target.
报错: Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. java.lang ...
- Erlang Process input queue
http://www.cnblogs.com/me-sa/archive/2011/11/05/erlang0012.html Erlang进程有自己的消息队列来保存接收到的消息,新接收到的消息放在队 ...
- require.js的用法详解
require.js的诞生是为了解决两大问题,第一实现js文件的异步加载,避免网页失去响应,第二管理模块之间的依赖性,便于代码的编写和维护. 一.为什么要用require.js? 最早的时候,所有Ja ...
- 【BZOJ 1014】 [JSOI2008]火星人prefix
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 让你在线查询最长公共前缀. 支持单节点修改; 插入操作; [题解] / ...
- 【BZOJ 1028】[JSOI2007]麻将
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1028 [题意] [题解] /* 枚举新加入的一张牌是哪一张牌; 然后尝试把它加进去; ...
- iOS CALayer使用
CALayer使用 iOS的设备中,我们之所以能看到各种各样的控件.文字.图片,都是Core Animation框架的功劳.它通过图层的合成,最终显示在屏幕上.而今天这篇文章讲的就是Core Anim ...
- gcc/g++ 的参数总结(二)
gcc 参数总结 如果是 c++,直接将 gcc 改为 g++ 即可. 1. gcc 编译流程 预处理,Pre-Processing:gcc -E test.c -o test.i //.i文件 编译 ...
- 解决mysql连接异常—-com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception
DBCP连接池连接MySql数据库时,一奇葩数据库设置为30秒内无请求自动断开.超时后链接无法关闭,活动链接数飞奔,最后挂掉. 网上找了一圈,一般是这三种,方法一pass,方法二测试无效可能设置错了吧 ...
- 常见Python 中pip用法(待继续添加)
常见pip用法 * pip install numpy --安装包numpy * pip uninstall numpy --卸载包numpy * pip ...