关于rpc简介、原理、实例-缘于difx

关于rpc简介、原理、实例缘于difx

       今天稍微研究了一下关于rpc的东东,主要是因为Pro.Z碰到的问题,在解决了以后,对rpc产生了一些兴趣,考虑到我目前的程序也可以从比较底层的socket方式概率为rpc方式,看的过程中,看到了一个网上的实例教程,估计已经转载了N遍了,所以有几个错误,包括rpc unknown protocalconfliction definecannot register service等,在测试的时候也进行了一些改正,并且进行了测试。

       单单是这个小程序,就可以做一个时间服务器性质的程序了。

简介

在传统的编程概念中,过程是由程序员在本地编译完成,并只能局限在本地运行的一段代码,也即其主程序和过程之间的运行关系是本地调用关系。因此这种结构在网络日益发展的今天已无法适应实际需求。总所周知,传统过程调用模式无法充分利用网络上其他主机的资源(如CPUMemory等),也无法提高代码在实体间的共享程度,使得主机资源大量浪费。

      通过RPC我们可以充分利用非共享内存的多处理器环境(例如通过局域网连接得多台工作站),这样可以简便地将你的应用分布在多台工作站上,应用程序就像运行在一个多处理器的计算机上一样。你可以方便的实现过程代码共享,提高系统资源的利用率,也可以将以大量数值处理的操作放在处理能力较强的系统上运行,从而减轻前端机的负担。

RPC的结构原理及其调用机制

如前所述RPC其实也是种C/S的编程模式,有点类似C/S Socket 编程模式,但要比它

更高一层。当我们在建立RPC服务以后,客户端的调用参数通过底层的RPC传输通道,可以是UDP,也可以是TCP(也即TI-RPC—无关性传输),并根据传输前所提供的目的地址及RPC上层应用程序号转至相应的RPC应用程序服务端,且此时的客户端处于等待状态,直至收到应答或Time Out超时信号。具体的流程图如F1。当服务器端获得请求消息,则会根据注册RPC时告诉RPC系统的例程入口地址,执行相应的操作,并将结果返回至客户端。

 
  clip_image002


F1

当一次RPC调用结束后,相应线程发送相应的信号,客户端程序才会继续运行。

在这个过程中,一个远程过程是有三个要素来唯一确定的:程序号、版本号和过程号。

程序号是用来区别一组相关的并且具有唯一过程好的远程过程。一个程序可以有一个或几个不同的版本,而每个版本的程序都包含一系列能被远程调用的过程,通过版本的引入,使得不同版本下的RPC能同时提供服务。每个版本都包含有许多可供远程调用的过程,每个过程则有其唯一标示的过程号。

基于RPC的应用系统开发

通过以上对RPC原理的简介后,我们再来继续讨论如何来开发基于RPC的应用系统。

一般而言在开发RPC时,我们通常分为三个步骤:

a、 定义说明客户/服务器的通信协议:这里所说的通信协议是指定义服务过程的名称、调用参数的数据类型和返回参数的数据类型,还包括底层传输类型(可以是UDPTCP),当然也可以由RPC底层函数自动选择连接类型建立TI-RPC。最简单的协议生成的方法是采用协议编译工具,常用的有Rpcgen,我会在后面实例中详细描述其使用方法。

b、  开发客户端程序。

c、  开发服务器端程序。

开发客户端和服务器端的程序时,RPC提供了我们不同层次的开发例程调用接口。不同层次的接口提供了对RPC不同程度控制。一般可分为5个等级的编程接口,接下来我们分别讨论一下各层所提供的功能函数。

简单层例程

简单层是面向普通RPC应用,为了快速开发RPC应用服务而设计的,他提供了如下功能函数。

  函数名

             功能描述

Rpc_reg( )

在一特定类型的传输层上注册某个过程,来作为提供服务的RPC程序

Rpc_call( )

远程调用在指定主机上指定的过程

Rpc_Broadcast( )

向指定类型的所有传输端口上广播一个远程过程调用请求

                                

高层例程

在这一层,程序需要在发出调用请求前先创建一个客户端句柄,或是在侦听请求前先建立一个服务器端句柄。程序在该层可以自由的将自己的应用绑在所有的传输端口上,它提供了如下功能函数。

          

  函数名

             功能描述

Clnt_create( )

程序通过这个功能调用,告诉底层RPC服务器的位置及其传输类型

Clnt_create_timed( )

定义每次尝试连接的超时最大时间

Svc_create( )

在指定类型的传输端口上建立服务器句柄,告诉底层RPC事件过程的相应入口地址

Clnt_call()

向服务器端发出一个RPC调用请求

中间层例程

中间层向程序提供更为详细的RPC控制接口,而这一层的代码变得更为复杂,但运行也更为有效,它提供了如下功能函数。

  函数名

             功能描述

Clnt_tp_create( )

在指定的传输端口上建立客户端句柄

Clnt_tp_create_timed( )

定义最大传输时延

Svc_tp_creaet( )

在指定的传输端口上建立服务句柄

Clnt_call( )

向服务器端发出RPC调用请求

                

专家层例程

这层提供了更多的一系列与传输相关的功能调用,它提供了如下功能函数。

 

  函数名

             功能描述

Clnt_tli_create( )

在指定的传输端口上建立客户端句柄

Svc_tli_create( )

在指定的传输端口上建立服务句柄

Rpcb_set( )

通过调用rpcbindRPC服务和网络地址做映射

Rpcb_unset( )

删除rpcb_set( ) 所建的映射关系

Rpcb_getaddr( )

调用rpcbind来犯会指定RPC服务所对应的传输地址

Svc_reg( )

将指定的程序和版本号与相应的时间例程建起关联

Svc_ureg( )

删除有svc_reg( ) 所建的关联

Clnt_call( )

客户端向指定的服务器端发起RPC请求

底层例程

该层提供了所有对传输选项进行控制的调用接口,它提供了如下功能函数。

  函数名

             功能描述

Clnt_dg_create( )

采用无连接方式向远程过程在客户端建立客户句柄

Svc_dg_create( )

采用无连接方式建立服务句柄

Clnt_vc_create( )

采用面向连接的方式建立客户句柄

Svc_vc_create( )

采用面向连接的方式建立RPC服务句柄

Clnt_call( )

客户端向服务器端发送调用请求

实例介绍

以下我将通过实例向读者介绍通过简单层RPC的实现方法。通常在此过程中我们将使用RPC协议编译工具—RpcgenRpcgen 工具用来生成远程程序接口模块,它将以RPC语言书写的源代码进行编译,Rpc 语言在结构和语法上同C语言相似。由Rpcgen 编译生成的C源程序可以直接用C编译器进行编译,因此整个编译工作将分为两个部分。Rpcgen的源程序以.x结尾,通过其编译将生成如下文件:

a) 一个头文件(.h)包括服务器和客户端程序变量、常量、类型等说明。

b) 一系列的XDR例程,它可以对头文件中定义的数据类型进行处理。

c)  一个Server 端的标准程序框架。

d) 一个Client 端的标准程序框架。

   当然,这些输出可以是选择性的,Rpcgen 的编译选项说明如下:

  选项

功能

‘-‘ a

生成所有的模板文件

‘-‘ Sc

生成客户端的模板文件

‘-‘ Ss

生成服务器端的模板文件

‘-‘ Sm

生成Makefile 文件

      (详见Solaris Rpcgen Manaul)

 

Rpcgen 源程序 time.x:

/* time.x: Remote time printing protocol */

program TIMEPROG {

version PRINTIMEVERS {

string PRINTIME(string) = 1;

} = 1;

} = 0x20000001;

 

time_proc.c源程序:

/* time_proc.c: implementation of the remote procedure "printime" */ 

#include <stdio.h>

#include <rpc/rpc.h> /* always needed */

#include "time.h" /* time.h will be generated by rpcgen */

#include <time.h>

/* Remote version of "printime" */

char ** printime_1_svc(char **msg,struct svc_req *req)



{

static char * result; /* must be static! */

static char tmp_char[100];

time_t rawtime;



FILE *f;



f = fopen("/tmp/rpc_result", "a+");

if (f == (FILE *)NULL) {

strcpy(tmp_char,”Error”);

result = tmp_char;;

return (&result);

}

fprintf(f, "%sn", *msg); //used for debugging

fclose(f);

time(&rawtime);

sprintf(tmp_char,"Current time is :%s",ctime(&rawtime));

result =tmp_char;

return (&result);

}

 

rtime.c源代码

/*

* rtime.c: remote version

* of "printime.c"

*/



#include <stdio.h>

#include "time.h" /* time.h generated by rpcgen */



main(int argc, char **argv)



{

CLIENT *clnt;

char *result;

char *server;

char *message;



if (argc != 3) {



fprintf(stderr, "usage: %s host messagen", argv[0]);

exit(1);

}



server = argv[1];

message = argv[2];



/*

* Create client "handle" used for

* calling TIMEPROG on the server

* designated on the command line.

*/



//clnt = clnt_create(server, TIMEPROG, PRINTIMEVERS, "visible");

clnt = clnt_create(server, TIMEPROG, PRINTIMEVERS, "TCP");





if (clnt == (CLIENT *)NULL) {

/*

* Couldn't establish connection

* with server.

* Print error message and die.

*/



clnt_pcreateerror(server);

exit(1);

}



/*



* Call the remote procedure

* "printime" on the server

*/



result =*printime_1(&message,clnt);

if (result== (char *)NULL) {

/*

* An error occurred while calling

* the server.

* Print error message and die.

*/



clnt_perror(clnt, server);

exit(1);

}



/* Okay, we successfully called

* the remote procedure.

*/



if (strcmp(result,“Error”) == 0) {



/*

* Server was unable to print

* the time.

* Print error message and die.

*/



fprintf(stderr, "%s: could not get the timen",argv[0]);

exit(1);

}

printf("From the Time Server ...%sn",result);

clnt_destroy( clnt );

exit(0);

}

 

编译方法

   有了以上的三段代码后,就可用rpcgen 编译工具进行RPC协议编译,命令如下:

   $rpcgen time.x

   rpcgen 会自动生成time.htime_svc.ctime_clnt.c

   再用系统提供的gcc进行C的编译,命令如下:

   $gcc rtime.c time_clnt.c -o rtime –lnsl                            //客户端编译

$gcc time_proc.c time_svc.c -o time_server  –lnsl     error//服务器端编译

编译成功后即可在Server端运行time_server,立即将该服务绑定在rpc服务端口上提供服务。在客户端运行./rdate hostname msg (msg 是一字符串,笔者用来测试时建立的),立即会返回hostname 端的时间。

出错问题

Cannot register service

RPC: Authentication error; why = Client credential too weak unable to register (TIMEPROG, PRINTIMEVERS, udp)

解决方法:使用root账户即可

time_proc.c:7: error: conflicting types for printime_1?

源程序time_proc.c中报错

解决方法,改为char ** printime_1_svc(char **msg,struct svc_req *req)即可。

RPC: Unknown protocol

      这个原因可能是rpc依赖包没有安装,或者使用函数clnt_create的时候,最后一个参数应该不使用visible,而是tcp。

The DiFX Software Correlator at IRA and Italian VLBI

by John Morgan

Institute of Radio Astronomy, Bologna

IRA Coffee Talk

28 March 2008

相关器

       每个scan每个天线一个文件。

相关后得到UV数据(fits文件)

l  Time 时间

l  Baseline 基线

l  (IF)

l  (channel) 通道

l  (polarisation) 偏振极化

 

硬件处理机还是蛮通用的,比如:

天线

l  ALMAThe  Atacama Large Millimeter/submillimeter Array (ALMA), an international partnership of Europe, North America and East Asia in cooperation with the Republic of Chile, is the largest astronomical project in existence. ALMA will be a single telescope of revolutionary design, composed initially of 66 high precision antennas located on the Chajnantor plateau, 5000 meters altitude in northern Chile.

clip_image002

l  EVLAThe Expanded Very Large Array Project: A Radio Telescope to Resolve Cosmic Evolution

clip_image004

l  e-MERLINThe Multi-Element Radio Linked Interferometer Network (MERLIN) is an interferometer array of radio telescopes spread across England. The array is run from Jodrell Bank Observatory in Cheshire by the University of Manchester on behalf of STFC as a National Facility.

clip_image006

VLBI

l  Bonn

l  JIVE

n  The Joint Institute for VLBI in Europe was formally established in 1993 by the Consortium for VLBI in Europe. The Institute is located in Dwingeloo, the Netherlands, and hosted by ASTRON, the Netherlands Institute for Radio Astronomy.

clip_image008

l  VLBA

n  The Very Long Baseline Array (VLBA) is an interferometer consisting of 10 identical antennas on transcontinental baselines up to 8000 km (Mauna Kea, Hawaii to St. Croix, Virgin Islands). The VLBA is controlled remotely from the Science Operations Center in Socorro, New Mexico. Each VLBA station consists of a 25 m antenna and an adjacent control building. The received signals are amplified, digitized, and recorded on fast, high capacity recorders. The recorded data are sent from the individual VLBA stations to the correlator in Socorro.

clip_image010

 

软件相关处理正变得越来越流行。比如国际低频阵列LOFARlow- frequency acquisition and ranging),运行在IBMblue gene上。

也有通用的就是DiFX

l  在澳大利亚的斯温伯恩研发

l  是的任何的x86集群都可以作为相关器

l  许多的机构正在探索这个软件的潜在价值

n  Bologna 博洛尼亚

n  Cagliari 卡利亚里

n  Bonn 波恩

n  NRAO

软件相关处理的优势

l  在通道数目和积分时间上没有硬件限制

n  Spectral-line VLBI

n  Wide-field VLBI

l  相关的速度仅仅受限于计算机(在目前集群的发展下不用顾忌)

n  e-VLBI is possible if the correlator is real-time

l  DiFX也有pulsar binning 模式

l  不同的相关器可以使用不同的参数

n  Can correlate the calibrator first

n  Can correlate several times shifting the center of the field

软件相关的流程

       相关本身是比较简单的,就是需要输入的文件比较多。

对基于NRAO-DiFX版本的:

l  Collection of software tools

l  Designed to give identical output to the VLBA Correlator

l  However VLBA observations use different control files

clip_image012

 

使用python脚本来控制进程。也可以通过一个脚本来控制整个进程从宽频带数据到结果图像。

意大利的VLBI

SRT

l  Sardinia

l  Medicina

l  Noto

l  Matera

 

clip_image014

clip_image016