「javarmi使用」JavaRMI使用接口化编程

博主:adminadmin 2022-11-21 18:25:07 45

今天给各位分享javarmi使用的知识,其中也会对JavaRMI使用接口化编程进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

哪些端口是通过java RMI连接使用

RMI的优势

这种机制给分布计算的系统设计、编程都带来了极大的方便。只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。 

1、面向对象: 

RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。也就是说,可以将类似Java Hash表这样的复杂类型作为一个参数进行传递。

2、可移动属性: 

RMI可将属性从客户机移动到服务器,或者从服务器移动到客户机。

3、设计方式: 

对象传递功能使你可以在分布式计算中充分利用面向对象技术的强大功能,如二层和三层结构系统。如果用户能够传递属性,那么就可以在自己的解决方案中使用面向对象的设计方式。所有面向对象的设计方式无不依靠不同的属性来发挥功能,如果不能传递完整的对象——包括实现和类型——就会失去设计方式上所提供的优点。

4、安全性: 

RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。

5、便于编写和使用 

RMI使得Java远程服务程序和访问这些服务程序的Java客户程序的编写工作变得轻松、简单。远程接口实际上就是Java接口。为了实现RMI的功能必须创建远程对象任何可以被远程调用的对象必须实现远程接口。但远程接口本身并不包含任何方法。因而需要创建一个新的接口来扩展远程接口。新接口将包含所有可以远程调用的方法。远程对象必须实现这个新接口,由于新的接口扩展了远程接口,实现了新接口,就满足了远程对象对实现远程接口的要求,所实现的每个对象都将作为远程对象引用。 

一个国外的PPT上还还总结到: 

Java RMI Advantages: 

Full object support 

Cross platform. capabilities 

Robust communications 

Large objects 

Security for client and servers 

Distribution/updates of codes

RMI的劣势

从上面的过程来看,RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。这也是RMI的局限性之一。这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。

RMI的局限性之二是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,对于不同语言间的通讯可以考虑用Web Service或者公用对象请求代理体系(CORBA)来实现。 

一个国外的PPT上也总结到: 

Java RMI Disadvantages: 

Java RMI only supports Java 

Proprietary protocol by single vendor 

Requires RMI-lookup 

Requires non-standard port

RMI与Socket的比较

RMI技术比较socket的网络编程主要有以下几个方面: 

第一、RMI是面向对象的,而后者不是。 

第二、RMI是与语言相绑定的。比如当你使用Java RMI技术的时候,客户端与服务器端都必须使用Java开发。而socket的网络编程是使用独立于开发语言的,甚至独立于平台。基于socket的网络编程,客户端与服务器端可以使用不同开发语言和不同的平台。 

第三、从网络协议栈的观点来看,RMI与socket的网络编程处于不同层次上。基于socket的网络编程位于TCP协议之上,而RMI在TCP协议之上,又定义了自己的应用协议,其传输层采用的是Java远程方法协议(JRMP)。可见,在网络协议栈上,基于RMI的应用位置更高一些,这也决定了,与socket的网络编程相比,RMI会丧失一些灵活性和可控性,但是好处是它带给了应用开发者更多的简洁,方便和易用。比如:如果你用的是RMI,你不需要关心消息是怎么序列化的,你只需要像本地方法调用一样,使用RMI。代价是:应用开发者无法很好地控制消息的序列化机制。 

第四、这是最后一点不同,我认为也是比较重要的一点,就是两种方法的性能比较,其往往决定着你将使用那种技术来开发你的应用。 

实验的结果是:RMI与TCP based socket相比,传输相同的有效数据,RMI需要占用更多的网络带宽(protocol overhead)。从这里,我们可以得出一个一般性的结论:RMI主要是用于远程方法的”调用“(RMI是多么的名符其实:)),其技术内涵强调的是 “调用”,基于此,我能想到的是:移动计算,和远程控制,当你的应用不需要在client与server之间传输大量的数据时,RMI是较好的选择,它简洁、易于开发。但是,一旦你的应用需要在client与server之间传输大量的数据,极端的,比如FTP应用,则RMI是不适合的,我们应该使用 socket。

PS: RMI的效率还是很高的,一般情况下会比Hessian更高效,比Web Service更是高效很多;当然和socket这种东东相比,当然要低效一点了,socket更底层一些啊。RMI的具体实现,依然是依赖于底层的Socket编程。

一个简单的RMI系统,一般可以分成4个文件,下面来介绍各个文件的创建和作用

第一步:创建一个远程对象接口

import java.rmi.Remote;

import java.rmi.RemoteException;

/*

* 这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象

* 我们可供远程调用的方法就是通过这里开公开

*/ public interface IRMI extends Remote{

public String invoke() throws RemoteException;

} 12345678910

第二步:创建接口的具体实现类

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

/*

* 远程对象的实现

* 公开方法的具体实现就是这里定义的

*/ public class IRMIImpl extends UnicastRemoteObject implements IRMI {

protected IRMIImpl() throws RemoteException {

super(); // 这个实现必须有一个显式的构造函数,并且要抛出一个RemoteException异常

}

private static final long serialVersionUID = 6131922116577454476L;

public String invoke() throws RemoteException {  //该方法公开

return "hello,world!";

}

public String tryInvoke() throws RemoteException{ //该方法未公开,若要公开请在接口中定义

return "try to remote me";

}

} 1234567891011121314151617181920212223

第三步:创建RMI服务器

import java.rmi.Naming;

import java.rmi.registry.LocateRegistry;

import java.rmi.registry.Registry;

/*

* 远程对象的注册类 该类应该在服务器端执行,执行之后

* 该机器将变为RMI服务器 客户端可以通过正确的url来访问

* 服务器上的远程对象,执行对外报露的方法

*/ public class RMIServer {

static int port = 8888;

/*

* 创建一个Registry对象.

* LocateRegistry用于获取名字服务或创建名字服务.

* 调用LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry

* @return 返回一个Registry对象

*/

private static Registry createRegistry() {

Registry registry = null;

try {

registry = LocateRegistry.getRegistry(port); //如果该端口未被注册,则抛异常

registry.list(); //拿到该端口注册的rmi对象

} catch (final Exception e) {

try {

registry = LocateRegistry.createRegistry(port);//捕获异常,端口注册

} catch (final Exception ee) {

ee.printStackTrace();

}

}

return registry;

}

/**

* 将对象注册到rmi服务器上

*/

public static void bind() {

Registry registry =  createRegistry();

try {

IRMIImpl impl = new IRMIImpl();

registry.rebind("mytask", impl); //这就是绑定,client里lookup必须和"mytast"一样才能远程调用impl

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

try {

bind();

} catch (Exception e) {

e.printStackTrace();

}

}

} 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

上面是一种比较好的写法,如果只是要测试,可以直接在main()方法中写:

ImplementClass ic = new ImplementClass(); //具体实现类

Registry r = LocateRegistry.createRegistry(8888);

r.bind("mytask", ic);

//Naming.rebind("rmi://localhost:8888/mytask", ic); 可替换上句 1234

1.注册一个端口 2.在注册端口绑定taskName和implementClass 3.客户端就可以通过url和taskName来找到implementClass。

第四步:创建RMI客户端

import java.rmi.Naming;

public class RMIClient {

/**

* 调用远程对象中的方法

* @throws Exception

*/

public static void getRemoteObject() throws Exception{

/*得到远程发布的服务

返回与指定 name 关联的远程对象的引用(一个stub)*/

IRMI obj = (IRMI)Naming.lookup("rmi://localhost:"+RMIServer.port+"/mytask");  //注:通过接口拿

System.out.println(obj.invoke()); //调用远程服务的方法

}

public static void main(String[] args) {

try {

getRemoteObject();

} catch (Exception e) {

e.printStackTrace();

}

}

} 123456789101112131415161718192021222324

运行RMI系统:启动RMI服务器,启动客户端即可。

java RMI是什么意思啊?

RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。调用这样一个对象时,其参数为 "marshalled" 并将其从本地虚拟机发送到远程虚拟机(该远程虚拟机的参数为 "unmarshalled")上。该方法终止时,将编组来自远程机的结果并将结果发送到调用方的虚拟机。如果方法调用导致抛出异常,则该异常将指示给调用方。

android 怎么使用java rmi

1、定义一个远程接口

IHello.java代码如下:

import java.rmi.Remote;

public interface IHello extends Remote {

public String sayHello(String name) throws java.rmi.RemoteException;

}

2、实现远程的接口(服务端就在此远程接口的实现类中)

HelloImpl.java代码如下:

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements IHello {

    // 这个实现必须有一个显式的构造函数,并且要抛出一个RemoteException异常  

    protected HelloImpl() throws RemoteException {

        super();

    }

    /**

     * 说明清楚此属性的业务含义

     */

    private static final long serialVersionUID = 4077329331699640331L;

    public String sayHello(String name) throws RemoteException {

        return "Hello " + name + " ^_^ ";

    }

    public static void main(String[] args) {

        try {

            IHello hello = new HelloImpl();

            java.rmi.Naming.rebind("rmi://localhost:1099/hello", hello);

            System.out.print("Ready");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

3、新建RMI客户端调用程序

Hello_RMI_Client.java代码如下:

import java.rmi.Naming;

public class Hello_RMI_Client {

    public static void main(String[] args) {

        try {

            IHello hello = (IHello) Naming.lookup("rmi://localhost:1099/hello");

                System.out.println(hello.sayHello("zhangxianxin"));

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

4、编译并运行

4.1 用javac命令编译IHello.java、HelloImpl.java、Hello_RMI_Client.java

javac *.java

4.2 用rmic命令生成桩和框架文件

rmic HelloImpl

成功执行完上面的命令可以发现生成一个HelloImpl_stub.class文件,如果JDK是使用Java2SDK,那么还可以发现多出一个HelloImpl_Skel.class文件。如果服务端程序与客户端程序在同一台机器上并在同一目录中,则可以省略掉接口实现类生成的桩和框架文件,但这就失去了使用RMI的意义,而如果要在不同的JVM上运行时,客户端程序就必须得依靠服务端运程方法实现的桩和框架文件以及接口类。

4.3 运行注册程序RMIRegistry,必须在包含刚写的类的目录下运行这个注册程序。

rmiregistry

注册程序开始运行了,不要管他,现在切换到另外一个控制台运行服务器

4.4 运行服务器HelloImpl

java HelloImpl

当启动成功出现Ready...... 这个服务器就开始工作了,把接口的实现加载到内存等待客户端的联接。现在切换到第三个控制台,启动我们的客户端。

4.5 启动客户端:为了在其他的机器运行客户端程序你需要一个远程接口(IHello.class) 和一个stub(HelloImpl_Stub.class)。 使用如下命令运行客户端

java Hello_RMI_Client

当运行成功会在控制台打印:Hello zhangxianxin() ^_^

备注:如果不想在控制台上开启RMI注册程序RMIRegistry的话,可在RMI服务类程序中添加LocateRegistry.createRegistry(1099); 如下所示:

修改后的HelloImpl.java代码如下:

import java.rmi.RemoteException;

import java.rmi.registry.LocateRegistry;

import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements IHello {

    // 这个实现必须有一个显式的构造函数,并且要抛出一个RemoteException异常  

    protected HelloImpl() throws RemoteException {

        super();

    }

    

    private static final long serialVersionUID = 4077329331699640331L;

    public String sayHello(String name) throws RemoteException {

        return "Hello " + name + " ^_^ ";

    }

    public static void main(String[] args) {

        try {

            IHello hello = new HelloImpl();

            LocateRegistry.createRegistry(1099); //加上此程序,就可以不要在控制台上开启RMI的注册程序,1099是RMI服务监视的默认端口

            java.rmi.Naming.rebind("rmi://localhost:1099/hello", hello);

            System.out.print("Ready");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    }

「javarmi使用」JavaRMI使用接口化编程

用通俗的语言解释一下Java的RMI、RPC适用于什么场景

RMI:java远程调用接口,比如,你在一台电脑要调用另外一台电脑的java对象,那就用RMI很方便,就像调用本机对象一样(几乎)

RPC:java远程方法调用,基本同上,就是RMI是java对象之间的调用,RPC可以不同语言。

如何rmi运行java程序?

首先在server端需要一个接口,继承自java.rmi.Remote

public interface Hello extends Remote {

public void say() throws RemoteException;

}

其次实现这个接口并继承java.rmi.server.UnicastRemoteObject

public class SayHello extends UnicastRemoteObject implements Hello{

protected SayHello() throws RemoteException{

super();

}

public String say() throws RemoteException {

return "Hello";

}

}

接着注册服务,绑定端口

public class Reg {

public static void main(String[] args) throws RemoteException,MalformedURLException{

LocateRegistry.createRegistry(1099);

SayHello sh = new SayHello();

Naming.rebind("rmi://localhost:1099/sh", sh);

System.out.println("注册完毕");

}

}

然后在客户端

public class Client {

public static void main(String[] args) throws RemoteException,MalformedURLException,NotBoundException{

Hello h = (Hello)Naming.lookup("rmi://localhost:1099/sh");

System.out.println(h.say());

}

}

即可

javarmi使用的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于JavaRMI使用接口化编程、javarmi使用的信息别忘了在本站进行查找喔。

The End

发布于:2022-11-21,除非注明,否则均为首码项目网原创文章,转载请注明出处。