中间件作业

来源:互联网 发布:windows上pdf阅读器 编辑:程序博客网 时间:2024/06/07 05:04

 

                                                                               

主要文件的代码:

fctrl_client_linux.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 "fctrl.h"

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

 

void

fctrl_1(char *host)

{

       CLIENT *clnt;

       int  *result_1;

       char *rfopen_1_path;

       char *rfopen_1_mode;

       u_int  *result_2;

       int rfread_1_handle;

       int rfread_1_size;

       char *rfread_1_buff;

       u_int  *result_3;

       int rfwrite_1_handle;

       int rfwrite_1_size;

       char *rfwrite_1_buff;

       int  *result_4;

       int rfclose_1_handle;

       int  *result_5;

       int rfseek_1_handle;

       long rfseek_1_offset;

       int rfseek_1_init_pos;

 

       clnt = clnt_create (host, FCTRL, VERSION, "udp");

       if (clnt == NULL)

       {

              clnt_pcreateerror (host);

              exit (1);

       }

      

       //----------

       rfopen_1_path = "test.txt";

       rfopen_1_mode = "w+";

       result_1 = rfopen_1(rfopen_1_path, rfopen_1_mode, clnt);

       if (result_1 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       int handle = *result_1;

       printf("rfopen result: %d/n", handle);

 

       //----------

       rfwrite_1_handle = handle;

       rfwrite_1_buff = "This is a test. /n /

       This line will be write into remote file.";

       rfwrite_1_size = strlen(rfwrite_1_buff);

       result_3 = rfwrite_1(rfwrite_1_handle, rfwrite_1_size, rfwrite_1_buff, clnt);

       if (result_3 == (u_int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfwrite result: %d/n", *result_3);

 

       //---------

       result_5 = rfseek_1(handle, 0, SEEK_SET, clnt);

       if (result_5 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfseek result: %d/n", *result_5);

 

       //---------

      

       struct read_ret * res;

       res = rfread_1(handle, 1024, clnt);

       if (result_2 == (u_int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfread result: [%d]/n%s/n", res->count, res->str);

      

       result_4 = rfclose_1(handle, clnt);

       if (result_4 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfclose result: %d/n", *result_4);

 

       clnt_destroy (clnt);

}

 

 

int

main (int argc, char *argv[])

{

       char *host;

 

       if (argc < 2) {

              printf ("usage: %s server_host/n", argv[0]);

              exit (1);

       }

       host = argv[1];

       fctrl_1 (host);

exit (0);

}

 

 

 

 

 

fctrl_client_windows.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 "fctrl.h"

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#pragma comment(lib, "D32-RPC.LIB")

 

void

fctrl_1(char *host)

{

       HCLIENT *clnt;

       int  *result_1;

       u_int  *result_2;

       int rfread_1_handle;

       int rfread_1_size;

       char *rfread_1_buff;

       u_int  *result_3;

       int rfwrite_1_handle;

       int rfwrite_1_size;

       char *rfwrite_1_buff;

       int  *result_4;

       int rfclose_1_handle;

       int  *result_5;

       int rfseek_1_handle;

       long rfseek_1_offset;

       int rfseek_1_init_pos;

       char * rfopen_1_path;

       char * rfopen_1_mode;

       int file_handle;

       long offset;

       int init_pos;

       struct read_ret * res;

       int read_count = 1024;

 

 

       clnt = clnt_create (host, FCTRL, VERSION, "udp");

       if (clnt == NULL)

       {

//           clnt_geterror (host);

              exit (1);

       }

      

       //----------

       rfopen_1_path = "test.txt";

       rfopen_1_mode = "w+";

       result_1 = rfopen_1(&rfopen_1_path, &rfopen_1_mode, clnt);

       if (result_1 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       file_handle = * result_1;

       printf("rfopen result: %d/n", file_handle);

 

       //----------

       rfwrite_1_handle = file_handle;

       rfwrite_1_buff = "This is a test. /n /

       This line will be write into remote file.";

       rfwrite_1_size = strlen(rfwrite_1_buff);

       result_3 = rfwrite_1(&rfwrite_1_handle, &rfwrite_1_size, &rfwrite_1_buff, clnt);

       if (result_3 == (u_int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfwrite result: %d/n", *result_3);

 

       //---------

       offset = 0;

       init_pos = SEEK_SET;

       result_5 = rfseek_1(&file_handle, &offset, &init_pos, clnt);

       if (result_5 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfseek result: %d/n", *result_5);

 

       //---------

      

       read_count = 1024;

 

       res = rfread_1(&file_handle, &read_count, clnt);

       if (result_2 == (u_int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfread result: [%d]/n%s/n", res->count, res->str);

      

       result_4 = rfclose_1(&file_handle, clnt);

       if (result_4 == (int *) NULL)

       {

              clnt_perror (clnt, "call failed");

       }

       printf("rfclose result: %d/n", *result_4);

 

}

 

int

main (int argc, char *argv[])

{

       char *host;

 

       if (argc < 2) {

              printf ("usage: %s server_host/n", argv[0]);

              exit (1);

       }

       host = argv[1];

       fctrl_1 (host);

       return 0;

}

 

 

 

 

 

 

 

fctrl_server.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 "fctrl.h"

#include <stdio.h>

 

int *

rfopen_1_svc(char *path, char *mode,  struct svc_req *rqstp)

{

       static int  result;

       printf("Client Call Procdure: rfopen(%s, %s)/n", path, mode);

       FILE * file = fopen(path, mode);

       if (file == NULL)

       {

              printf("fopen failed!");

       }

       result = (int) file;

       printf("Call Successed!: rfopen(%s, %s) = %d/n", path, mode, result);

       return &result;

}

 

read_ret *

rfread_1_svc(int handle, int size,  struct svc_req *rqstp)

{

       static read_ret  result;

       printf("Client Call Procdure: rfread(%d, %d)/n", handle, size);

       FILE * file = (FILE *) handle;

       result.str = (char *)malloc(sizeof(char) * size);

       memset(result.str, 0, size);

       result.count = fread(result.str, sizeof(char), size, file);

       printf("Call Successed!: rfread() = %d/n%s", result.count, result.str);

       return &result;

}

 

u_int *

rfwrite_1_svc(int handle, int size, char *buff,  struct svc_req *rqstp)

{

       static u_int  result;

       printf("Client Call Procdure: rfwrite(%d, %d, %s)/n", handle, size, buff);

       FILE * file = (FILE *) handle;

       result = fwrite(buff, sizeof(char), size, file);

       printf("Call Successed!: rfwrite() = %d/n", result);

 

       return &result;

}

 

int *

rfclose_1_svc(int handle,  struct svc_req *rqstp)

{

       static int  result;

       printf("Client Call Procdure: rfclose(%d)/n", handle);

       FILE * file = (FILE *) handle;

       result = fclose(file);

       printf("Call Successed!: rfclose() = %d/n", result);

       return &result;

}

 

int *

rfseek_1_svc(int handle, long offset, int init_pos,  struct svc_req *rqstp)

{

       static int  result;

       printf("Client Call Procdure: rfseek(%d, %ld, %d)/n", handle, offset, init_pos);

       FILE * file = (FILE *) handle;

       result = fseek(file, offset, init_pos);

       printf("Call Successed!: rfseek() = %d/n", result);

       return &result;

}

心得体会:

    刚开始接触RPC是挺恐慌的,不知道从那里着手,原理虽然了解,但具体到实际操作还是不一样的,学东西还是从简单到复杂一步一步来比较适应,一下子完成这个作业还是比较困难的。虽然这个作业花了不少时间,但对RPC的使用和操作流程有了一定的概念。最初开始是在UBUNTU环境下打算实现本地调用,调用功能也毕竟简单,就是从服务器读取系统时间然后在客户端现实。而且网上LINUX系统之间调用的资料比较多。
Linux下开发RPC程序流程如下:
1.
写一个rpc程序
    
test.x
2.
使用rpcgen生成必须的文件,通常是客户端和服务器端以及头文件
    $rpcgen test.x
3.
使用rpcgen生成服务器端和客户端的C语言代码
    $rpcgen -Ss -o test_server.c test.x
    $rpcgen -Sc -o test_client.c test.x
4.
生成Makefile
    $rpcgen -Sm test.x>Makefile
5.
编辑源文件,加入你想要的服务等
6.
编辑Makefile

7.执行测试

$./test_server

$./test_client 127.0.0.1

按这个流程下来最后发现一个问题,服务器无法启动。错误如下:

Cannot register service: RPC: Unable to receive; errno = Connection refused
unable to register (TESTPROG, VERSION, udp).

粗略知道PORTMAP是关于RPC端口映射的,UBUNTU10.04系统没有安装的。

解决方法如下:

安装portmap

$sudo apt-get install portmap

如果有了则启动

$sudo /etc/init.d/portmap start

接下来想办法就是平台移植,本地调用的话要安装虚拟机VMWARE,中途也遇到一些问题,比如在虚拟机中键盘无法使用。仍然按RPC程序文件名为text.x来说明,把客户端生存的文件test.h test_client.c test_clnt.c拷贝到windows环境下,在VS6.0的环境下新建一个WIN32控制台项目生成test_client.exe。运行之前需要把关于rpc的文件拷贝到VS6.0安装目录下的include文件夹,还要把pwrpc32.lib文件拷贝到项目所在的文件夹。在test_client.c文件开始出要加上#pragma comment(lib,"pwrpc32.lib")

但是运行的时候提示缺少pwrpc32.dll,可以从网上下一个考到系统的system32中或者项目所在目录的debug文件夹下。接下来就可以在WINDOWSDOS环境下运行test_client.exe来测试。按这样的步骤在C源的客户端文件和服务器文件写好要读写文件,关闭打开文件的代码就可以实现WINDOWS客户端利用RPC的远程调用LINUX系统的服务器了。