- 浏览: 664443 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
sztime:
可以在文本框上绑定事件来禁用回车键, 我就是这样做的.在IE中 ...
form 回车自动提交问题 -
damoqiongqiu:
非常好的文章,很透彻不过有一句话小僧腆着脸补充一下:“1111 ...
为什么要用补码来做存储 -
wuyizhong:
原来如此啊。
form 回车自动提交问题 -
luliangy:
谢楼主~!
用C语言扩展Python的功能 -
kwong:
很有用,谢谢
火狐和IE 对css 样式解释的差异
在查看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 */
#include "test.h"
/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
char **
test_1(char **argp, CLIENT *clnt)
{
static char *clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call (clnt, TEST,
(xdrproc_t) xdr_wrapstring, (caddr_t) argp,
(xdrproc_t) xdr_wrapstring, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
说明:这是一个客户端调用函数,即客户端代码需要用到此函数。
源文件test.h内容如下:/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _TEST_H_RPCGEN
#define _TEST_H_RPCGEN
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TESTPROG 87654321
#define VERSION 1
#if defined(__STDC__) || defined(__cplusplus)
#define TEST 1
extern char ** test_1(char **, CLIENT *);
extern char ** test_1_svc(char **, struct svc_req *);
extern int testprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define TEST 1
extern char ** test_1();
extern char ** test_1_svc();
extern int testprog_1_freeresult ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_TEST_H_RPCGEN */
说明:这里定义了一些公用头文件。
源文件test_svc.c内容如下:/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
static void
testprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
char *test_1_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
case TEST:
_xdr_argument = (xdrproc_t) xdr_wrapstring;
_xdr_result = (xdrproc_t) xdr_wrapstring;
local = (char *(*)(char *, struct svc_req *)) test_1_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit (1);
}
return;
}
int
main (int argc, char **argv)
{
register SVCXPRT *transp;
pmap_unset (TESTPROG, VERSION);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create udp service.");
exit(1);
}
if (!svc_register(transp, TESTPROG, VERSION, testprog_1, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (TESTPROG, VERSION, udp).");
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create tcp service.");
exit(1);
}
if (!svc_register(transp, TESTPROG, VERSION, testprog_1, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (TESTPROG, VERSION, tcp).");
exit(1);
}
svc_run ();
fprintf (stderr, "%s", "svc_run returned");
exit (1);
/* NOTREACHED */
}
说明:这是一个标准的服务器端代码。
运行下列命令生成一个客户端源文件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
testprog_1(char *host)
{
CLIENT *clnt;
char * *result_1;
char * test_1_arg;
#ifndef DEBUG
clnt = clnt_create (host, TESTPROG, VERSION, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit (1);
}
#endif /* DEBUG */
result_1 = test_1(&test_1_arg, clnt);
if (result_1 == (char **) NULL) {
clnt_perror (clnt, "call failed");
}
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
}
int
main (int argc, char *argv[])
{
char *host;
if (argc < 2) {
printf ("usage: %s server_host\n", argv[0]);
exit (1);
}
host = argv[1];
testprog_1 (host);
exit (0);
}
运行这个命令生成服务端源文件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 **
test_1_svc(char **argp, struct svc_req *rqstp)
{
static char * result;
/*
* insert server code here
*/
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 **
test_1_svc(char **argp, struct svc_req *rqstp)
{
static char * result;
static char tmp_char[128];
time_t rawtime;
/*
* insert server code here
*/
if( time(&rawtime) == ((time_t)-1) ) {
strcpy(tmp_char, "Error");
result = tmp_char;
return &result;
}
sprintf(tmp_char, "服务器当前时间是 :%s", ctime(&rawtime));
result = tmp_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);
#ifndef DEBUG
clnt = clnt_create (host, TESTPROG, VERSION, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit (1);
}
#endif /* DEBUG */
result_1 = test_1(&test_1_arg, clnt);
if (result_1 == (char **) NULL) {
clnt_perror (clnt, "call failed");
}
if (strcmp(*result_1, "Error") == 0) {
fprintf(stderr, "%s: could not get the time\n", host);
exit(1);
}
printf("收到消息 ... %s\n", *result_1);
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
}
重新运行上述编译命令编译生成程序: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
SERVER = test_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = test.x
TARGETS_SVC.c =
TARGETS_CLNT.c =
TARGETS =
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g
LDLIBS += -lnsl
RPCGENFLAGS =
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
rpcgen $(RPCGENFLAGS) $(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)
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)
由于我们手工生成了源文件,所以要修改一下这个Makefile,修改后如下:
# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = test_client
SERVER = test_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = test.x
TARGETS_SVC.c = test_clnt.c test_srv_func.c test_svc.c
TARGETS_CLNT.c = test_clnt.c test_client.c
TARGETS = test.h test_clnt.c test_svc.c
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g
LDLIBS += -lnsl
RPCGENFLAGS =
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
rpcgen $(RPCGENFLAGS) $(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)
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) *~
发表评论
-
strlcpy 的历史
2012-11-05 18:51 711strlcpy 并不属于 ANSI C,至今也还不是标准 ... -
c中的移位操作
2012-04-12 18:18 1013位移位运算符是将数据看成二进制数,对其进行向左或向 ... -
为什么要用补码来做存储
2012-04-12 18:02 2242看了些补码的知识,摘抄了些,自己整理了些。 顺便带着两个 ... -
google test 使用
2009-01-03 13:59 3554安装: 下载Google C++ Testi ... -
string 的 data() 和c_str()
2008-12-24 01:17 1257data 是字符数组,里面有 '\0 '当然也不会 ... -
C/C++ unit testing tools (18 found)
2008-12-19 01:27 1979C/C++ unit testing tools (18 f ... -
climits中的符号常量
2008-12-10 11:43 1152climits中的符号常量 符号常量 ... -
ICE初次
2008-09-02 01:48 1901按照某人的说法:跨平台的C++网络编程ICE才是王道。于是,我 ... -
对 pthread_cond_wait 的错误理解
2008-08-28 15:52 2098在线程的调度中经常会用到 pthread_cond_wait ... -
环形缓冲
2008-08-27 17:20 960/** * Copyright (c) 2008, ×××研 ... -
C++中重载操作符时什么时候定义成友元,什么时候定义为成员方法
2008-07-10 18:05 3551在C++语言中,可以用关键字operator加上运算符来表示函 ... -
c++中的存储类型
2008-07-06 00:46 1923存储类型是从变量的存 ... -
libevent 一个time server
2008-05-19 11:20 1307#include <netinet/in.h> # ... -
自己动手改写komodo sourcetree插件 对C/C++的支持
2008-04-16 22:11 1405其实很简单了, 找到sourcetree.js 的 ... -
GNU C的 __attribute__ 机制
2008-04-15 15:34 775GNU C 的一大特色(却不被初学者所知)就是 __attri ... -
module的认识和写法
2008-04-15 15:29 721不知道在什幺时候,Linux 出现了 module 这种东西, ... -
dynamic_cast、static_cast、const_cast 和 reinterp
2008-04-10 15:16 1392dynamic_cast、static_cast、co ... -
static_cast、dynamic_cast、reinterpret_cast、和const_c
2008-04-10 15:14 6243static_cast、dynamic_cast、reinte ... -
关于Linux下C/C++程序编译
2007-08-23 18:15 3687在编译之前我们需要 ... -
使用 setfill、setw 和 setprecision 基数的示例
2007-08-23 19:00 2731使用 setfill、setw 和 setprecision ...
相关推荐
本资料包“RPC.tar.gz_linux rpc_rpc_rpc linux_rpc linux_C”提供了C语言实现的RPC功能,旨在帮助开发者理解和应用Linux环境下的RPC技术。 首先,让我们深入理解RPC的工作原理。RPC的核心思想是客户端发起一个请求...
RPC(Remote Procedure ...这个过程中涉及的知识点包括RPC协议原理、XDR编码、`rpcgen`工具的使用、C语言编程、网络编程以及服务器和客户端之间的交互。希望这个详尽的指南能帮助你理解和实现RPC在Linux环境下的应用。
总结来说,"中间件的远程文件操作"涉及到的技术包括中间件设计、ONC RPC协议的使用、跨平台通信、Linux服务器管理和Windows客户端编程。通过熟练掌握这些知识点,开发者可以构建出高效、可靠的分布式文件系统解决...
RPC(Remote Procedure Call)是一种网络通信协议,它允许一台计算机通过网络向另一台计算机执行远程调用,就像本地调用一样。在Linux系统中,RPC常用于分布式系统间的通信,例如文件共享、打印服务等。"rpc_pipe"指...
第十二章 BPC远程过程调用原理和实践 12.1 RPC的原理 12.1.1 XDR的更进一步 12.1.2 本地函数调用的过程 12.1.3 用远程调用来虚拟本地调用 12.2 RPC的实现 12.2.1 远程过程的标识 ...
它可以将任何单体架构系统的本地方法调用重构为基于TCP网络的RPC远程方法调用。该框架实现了同一台机器的不同进程之间或不同机器之间的服务调用。它适用于将单体架构系统拆分为基.zip C++是一种面向对象的计算机程序...
在IT行业中,网络编程是至关重要的一环,而与之相关的函数和系统调用则构成了网络通信的基础。在给定的标题“get_myaddress.rar_GetHostByName_gethostbyname linux”和描述“use gethostbyname, which would invoke...
6. **sunrpc**:实现了Sun Microsystems的远程过程调用(RPC)协议,使不同计算机间的进程可以透明地调用对方的函数。 7. **intl**:提供国际化的支持,包括翻译和日期/时间格式化等功能,帮助程序适应全球用户的...
C语言是Linux内核和系统级编程的首选语言,因此我们可以预期rc-main.c包含了大量的系统调用和网络编程接口。 在rc-main.c中,我们可能会找到以下关键知识点: 1. **网络协议**:远程控制通常基于TCP/IP协议,可能...
" 暗示我们关注的是一个与 RxRPC(Remote eXecution RPC,远程执行远程过程调用)相关的Linux驱动程序,特别是关于数据包接收的部分。"Welcome!" 标签可能表示这是一个初始版本或对用户开放的版本,鼓励人们尝试使用...
主机进程通过远程过程调用(RPC)的形式调度GPU作业,支持GPU代码以类似C语言的形式编写,但包含特定注释以区分主机代码和不同类型的GPU内存数据。 #### NVCC编译流程详解 NVCC在CUDA开发环境中的作用至关重要,它...
J2EE平台、中间件如IBM CICS、BEA Tuxedo以及各种RPC协议(远程过程调用)成为了关键组件。 分布式数据库、应用服务器和Web前端的分布化,加上数据库同步、分区、缓存机制的引入,标志着软件架构进入了一个新的阶段...
其他可能用到的库有Apache的 APR(Apache Portable Runtime),用于跨平台的系统接口抽象,或者Google的gRPC,用于构建高性能的RPC(远程过程调用)框架。 在压缩包中的"CheckData_Modified_Files"很可能包含了修改...
DCE(Distributed Computing Environment)中的RPC(Remote Procedure Call)是常见的远程调用方式,但CICS也支持其他通信机制。Encina是CICS的一个分支,但由于不再发展,其地位逐渐被其他技术替代。 对于Java...
### Linux中BSD套接口开发的基础...- 使用远程过程调用(RPC)进行网络编程。 - 利用CORBA/distributed objects进行分布式对象编程。 通过深入研究这些主题,读者将能够掌握构建复杂网络应用程序所需的技能和知识。
信号用于广播事件,方法调用则类似于远程过程调用(RPC)。 4. **并发处理**:DBus使用异步模型处理消息,可以同时处理多个请求,提高了系统效率。 **在ARM架构上的移植** 1. **编译环境准备**:首先,你需要在...
标题中的“install-protoc-3.7.0-win64”指的是...它在分布式系统、RPC(远程过程调用)、持久化存储以及数据交换等场景中广泛应用。其优点在于轻量级、高效和语言无关性,使得它成为许多开发者的首选数据交换格式。
本文以Mandrake Linux 9.1(Kenrel 2.4.21)为例,介绍Linux下的安装和登录命令。 immortality按:请用ctrl+f在本页中查找某一部分的内容或某一命令的用法。 ----------------------------------------------------...