分布式计算——远程对象和远程方法的调用

分布式计算中有个远程方法的调用,在此基础上有个作业是在调用的远程方法中传递两个参数,

一个参数是本地对象,一个参数是远程对象。

下面就对这次的作业结果进行整理。

作业的要求如下:Java RMI远程方法调用实验:若一个方法是远程调用,其参数一是本地对象、参数二是远程对象,请实现程序,

在三台计算机上执行该程序,观察实验现象,报告实验结果。

作业要求图:

分布式计算——远程对象和远程方法的调用_第1张图片

==============================================================分割线

以下是部署过程:

因为需要三台计算机来实现,所以我是这么分布的。

计算机A作为客户端,也就是图中的机器A。

计算机B作为远程对象端 ,也就是图中的机器B。

计算机C作为服务器段,也就是图中的机器C。


在计算机A上的代码是这么部署的(共有四个文件):

LocalObj.java——用于生成本地对象

SomeClient.java(主文件)——本地客户端,用于连接远程对象和调用远程方法

SomeInterface.java(接口)——远程对象的存根,调用的远程方法为此接口实现对象的方法,其对象实现于机器C

RemoteObj.java(接口)——远程对象的存根,仅用于调用远程对象,其对象实现于机器B


在计算机B上的代码是这么部署的(共有三个文件):

SomeServer.java——B机器上的主文件,负责绑定对象和注册地址

RemoteObj.java(接口)——A机器上需要调用对象在B机器上的骨架

RemoteObjImpl.java——接口Remote的实现


在计算机C上的代码是这么部署的(共有五个文件):

SomeServer.java——C机器上的主文件,负责绑定对象和注册地址,以及方法的调用过程

RemoteObj.java(接口)——A机器上需要调用对象在C机器上的骨架

SomeInterface.java(接口)——A机器上需要调用的方法在C机器上的骨架

LocalObj.java——A机器上传递过来的本地对象在C机器上的骨架

SomeImple.java——A机器所调用的远程方法在C机器上的实现,也就是SomeInterface接口的实现

==============================================================分割线

以下是代码和一些供人理解的注释:(重复的代码不再贴出)

--------------------------------------------------------------------------小分割线

计算机A上的代码:

SomeClient.java:

import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.server.RemoteObject;

public class SomeClient {

	public static void main(String[] args){
		try{
		
			String portNum = "";	//定义rmi端口,如果为空,默认是1099
			LocalObj lo = new LocalObj("wmn", 18);	//本地对象的实例化,传递两个参数名字和年龄
			
			//以下是远程调用地址的初始化,上面是机器C的IP,下面机器B的IP
			String registryURL = "rmi://222.24.59.190:" + portNum + "/some";
			String registryURLro = "rmi://222.24.59.37:" + portNum + "/some";
			
			//以下是调用过程
			//h保存机器C中对象,通过h来调用机器C中实现的方法
			SomeInterface h = (SomeInterface)Naming.lookup(registryURL);
			//ro保存机器B中的对像,在通过h调用远程方法的时候需要将ro作为参数传递过去
			RemoteObj ro = (RemoteObj)Naming.lookup(registryURLro);
			
			//someMethod1(),就是调用的远程方法,此方法在机器A中没有实现,是在机器C中实现的
			String message = h.someMethod1(lo, ro);	//lo是本地对象,ro是远程对象
			int num = h.someMethod2(2);		//此处是测试的另一个远程方法
			System.out.println(message+" "+num);	//将执行结果打印出来。
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
}
LocalObj.java:

import java.io.Serializable;

public class LocalObj implements Serializable{

	String name;
	int age;
	
	public LocalObj(String name, int age){//本地的对象只是赋值两个属性,不做其他操作
		this.name = name;
		this.age = age;
	}
}
SomeInterface.java

import java.rmi.*;

public interface SomeInterface extends Remote {

	public String someMethod1(LocalObj lo, RemoteObj ro) throws java.rmi.RemoteException;
	public int someMethod2(int someParameter) throws java.rmi.RemoteException;
}
RemoteObj.java

import java.rmi.Remote;

public interface RemoteObj extends Remote{

	public String someMethod3() throws java.rmi.RemoteException;
}

--------------------------------------------------------------------------小分割线

计算机B上的代码:
SomeServer.java:

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class SomeServer {

	public static void main(String[] args){
		
		String protNum = "";	//初始化端口
		String registryURL;	//初始化url
		int RMIPortNum = 1099;	//初始化远程端口
		
		try{
			RemoteObjImpl remoteObjImpl = new RemoteObjImpl();	//接口对象的实现
			startRegistry(RMIPortNum);//开始注册,将远程端口1099传递进去
			registryURL = "rmi://222.24.59.37:" + protNum + "/some";
			Naming.rebind(registryURL, remoteObjImpl);//将registryURL绑定到远程对象exportedObj
			System.out.println("Some Server ready.");
		}catch(Exception ex){
			
			System.out.println("Exception in SomeServer.main" + ex);
		}
	}
	
	private static void startRegistry(int RMIPortNum) throws  RemoteException{
		
		try{
			Registry registry = LocateRegistry.getRegistry(RMIPortNum);
			String[] list = registry.list();
			//System.out.println(list.toString());
			
		}catch(Exception ex){
			
			System.out.println("RMI registry cannot be localhost at prot " + RMIPortNum);
			Registry registry = LocateRegistry.createRegistry(RMIPortNum);
			System.out.println("RMI registry created at prot " + RMIPortNum);
		}
	}
}

RemoteObj.java(同机器A中一样)

RemoteObjImpl.java:

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class RemoteObjImpl extends UnicastRemoteObject implements Serializable ,RemoteObj {

	protected RemoteObjImpl() throws RemoteException {
		super();
		
	}

	@Override
	public String someMethod3() throws RemoteException {
		
		return "Hello";
	}

}

--------------------------------------------------------------------------小分割线

计算机C上的代码:

SomeServer.java:

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class SomeServer {

	public static void main(String[] args){
		
		String protNum = "";	//初始化端口
		String registryURL;		//初始化url
		int RMIPortNum = 1099;	//初始化远程端口
		
		try{
			SomeImpl exportedObj = new SomeImpl();	//接口对象的实现
			startRegistry(RMIPortNum);		//开始注册,将远程端口1099传递进去
			registryURL = "rmi://222.24.59.190:" + protNum + "/some";
			Naming.rebind(registryURL, exportedObj);	//将registryURL绑定到远程对象exportedObj
			System.out.println("Some Server ready.");
		}catch(Exception ex){
			
			System.out.println("Exception in SomeServer.main" + ex);
		}
	}
	
	private static void startRegistry(int RMIPortNum) throws  RemoteException{
		
		try{
			Registry registry = LocateRegistry.getRegistry(RMIPortNum);
			String[] list = registry.list();
			System.out.println(list.toString());
			
		}catch(Exception ex){
			
			System.out.println("RMI registry cannot be localhost at prot " + RMIPortNum);
			Registry registry = LocateRegistry.createRegistry(RMIPortNum);
			System.out.println("RMI registry created at prot " + RMIPortNum);
		}
	}
}

RemoteObj.java (同机器A中的一样)

SomeInterface.java(同机器A中的一样)

LocalObj.java(同机器A中的一样)

SomeImple.java:

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class SomeImpl extends UnicastRemoteObject implements Serializable, SomeInterface {

	public SomeImpl() throws RemoteException{
		super();
	}
	
	@Override
	public String someMethod1(LocalObj lo, RemoteObj ro) throws RemoteException {

		lo.age = 24;//此处将A中传递进来的age改为24,以便证明确实将对象的属性改变了
		return lo.name+lo.age + ro.someMethod3();//此处返回ro.someMethod3(),来证明C机器调用B机器中方法是成功的
	}

	@Override
	public int someMethod2(int someParameter) throws RemoteException {
		
		int i = 6;
		i++;
		i = i*someParameter;
		return i;
	}

}

=======================================================分割线

结果的截图就不贴了
=======================================================分割线

注意问题:

三个计算机上的文件的包路径必须都相同。



你可能感兴趣的:(Java)