一、概述
C语言进行rpc编程时可以使用rpcgen自动生成分布式的程序代码文件,自己只需要编写***.x(RPC源文件),客户端、服务器端程序以及相应的接口就可以了(总结起来也就最多需要编写5个文件)。下面根据一个实现远程文件传输的rpc调用程序(客户端根据文件名请求文件,服务器端传回相应的文件),具体介绍使用rpcgen编写rpc调用的过程。
我们在本地一般的功能实现的代码如下:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#define MAXNAME 20
-
#define MAXLENGTH 1024
-
char * readfile(char *);
-
int main()
-
{
-
char name[MAXNAME];
-
printf("Enter File Name: ");
-
scanf("%s", name);
-
printf("%s", readfile(name));
-
}
-
-
char * readfile(char * name)
-
{
-
FILE *file = fopen(name, "r");
-
char * buf = (char *)malloc(sizeof(char)*MAXLENGTH);
-
if (file == NULL)
-
{
-
printf("File Cann't Be Open!");
-
return 0;
-
}
-
printf("The File Content is : /n");
-
while (fgets(buf, MAXLENGTH-1, file) != NULL)
-
{
-
return buf;
-
}
-
return NULL;
-
}
接下来我们用rpc来实现该函数的远程实现。
二、实现过程
1)首先写trans.x文件(该文件是RPC程序的源文件),该文件主要定义了RPC的程序号、版本号以及使用的传输函数。我们这个程序的trans.x的代码如下:
-
const MAXLENGTH =1024;
-
const MAXNAME = 20;
-
-
program FILETRANSPROG
-
{
-
version FILETRANSVERS
-
{
-
string READFILE(string) = 1;
-
}=1;//版本号,这个在后面用rpcgen生成的文件中,会在相应的函数后面加上该版本号
-
} = 99;//程序号
2)使用rpcgen trans.x命令将rpc的源文件进行解析。生成三个文件trans.h trans_clnt.c和trans_svc.c
3)编写客户端的常规函数(client.c)
-
#include "trans.h"
-
-
#define RMACHINE "127.0.0.1"
-
static char **ret;
-
CLIENT *handle;
-
-
char *readfile(char *);
-
int main(int argc,char **argv)
-
{
-
char name[MAXNAME];
-
char *buf;
-
printf("Enter File Name: ");
-
-
scanf("%s", name);
-
handle = clnt_create(RMACHINE, FILETRANSPROG, FILETRANSVERS,"tcp");//这句就相当于建立了一个socket连接,其中第一个参数表示的是服务器的ip地址,第二个参数表示的是rpc的程序号,第三个参数表示的版本号
-
-
if (handle == 0) {
-
-
printf("Could Not Connect To Remote Server./n");
-
-
exit(1);
-
-
}
-
-
buf = readfile(name);
-
-
printf("%s", buf);
-
-
return 0;
-
}
-
-
char *readfile(char *name)
-
{
-
char **arg;
-
arg = &name;
-
ret = readfile_1(arg,handle);//这个函数是通过rpcgen命令在trans.h中生成的。我们在这里直接调用就可以了
-
return ret ==NULL?NULL:*ret;
-
}
4)编写服务器端的常规函数(server.c)
-
#include <rpc/rpc.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include "trans.h"
-
#define MAXNAME 20
-
#define MAXLENGTH 1024
-
-
//该函数主要是打开文件,并读取文件的第一行,发送给客户端
-
char * readfile(char * name)
-
-
{
-
FILE *file = fopen(name, "r");
-
-
char * buf = (char *)malloc(sizeof(char)*MAXLENGTH);
-
if (file == NULL)
-
-
{
-
-
printf("File Cann't Be Open!");
-
-
return 0;
-
-
}
-
printf("The File Content is : \n");
-
-
while (fgets(buf, MAXLENGTH-1, file) != NULL)
-
-
{
-
-
printf("the buf is %s\n",buf);
-
return buf;
-
-
}
-
return NULL;
-
-
}
5)编写服务器端的接口函数(server_init.c)
-
#include <rpc/rpc.h>
-
#include <stdio.h>
-
-
#include "trans.h"
-
//该函数主要是把服务器端实现的readfile函数封装在reafile_1_svc函数中。这个函数为服务器的接口函数,是客户端和服务器之间进行通信的主要函数,服务器端读取的数据就是通过该函数传递给客户端的。而客户端就是通过read_1客户端接口函数来进行接收数据的。
-
static char *retcode;
-
char ** readfile_1_svc(char **w, struct svc_req *s)
-
{
-
retcode = readfile(*(char **)w);
-
return &retcode;
-
}
以上就是我们要实现的代码文件。总结来看我们就只需要实现trans.x、server.c(服务器端的常用函数)、client.c(客户端的常用函数)以及server_init.c(服务器端的接口函数)四个文件即可。
6)makefile文件:
-
TAR = testclient testserver
-
-
all:$(TAR)
-
-
testclient:testclient.o test_clnt.o
-
cc -O3 -o testclient testclient.o test_clnt.o
-
testclient.o:client.c
-
cc -O3 -o testclient.o -c client.c
-
test_clnt.o:trans_clnt.c
-
cc -O3 -o test_clnt.o -c trans_clnt.c
-
-
testserver:testserver.o test_srvint.o test_svc.o
-
cc -O3 $^ -o $@
-
test_svc.o:trans_svc.c
-
cc -O3 -o test_svc.o -c trans_svc.c
-
test_srvint.o:test_srvint.c
-
cc -O3 -o test_srvint.o -c test_srvint.c
-
testserver.o:server.c
-
cc -O3 -o testserver.o -c server.c
-
-
.PHONY:clean
-
clean:
-
rm *.o $(TAR)
上面就是该程序的所有的部分了。编译,然后执行就可以看到相应的效果了。
阅读(3088) | 评论(0) | 转发(0) |