RMI和Socket的比较及区别(转)

来源:互联网 发布:sistar shake it 编辑:程序博客网 时间:2024/06/05 19:27

一般来说,基于CS(client-server)软件架构的开发技术有很多种。比较常用的有:基于socket的网络编程、RPC、基于Java技术的 RMI(当然C#也有类似技术)、CORBA等。在这里我们只是对基于socket的网络编程与RMI作个对比,有助于我们了解它们各自的应用领域,帮助我们在面对一个具体问题的时候选用适合的技术。另外,本文所做的讨论可以认为是脱离了语言层面的东西,只是对技术的本身做一个讨论,无关乎你是用C++、 C#或Java 在开发。

一、RMI技术简介

        本文就以Java为例,简单介绍一下RMI技术。

        从Java1.1开始,远程方法调用作为Java分布式对象技术成为Java核心的API之一(在java.rmi.* 包)。RMI的引入,使得Java程序之间能够实现灵活的,可扩展的分布式通信。RMI允许Java对象存在于多个不同的地址空间,分布在不同的Java 虚拟机上。每一个地址空间可以在同一台主机上或者网络上不同的计算机上。由于远程方法调用跨越不同的虚拟机边界到不同的指定的地址空间,所以没有对象共享的全局变量,这就需要对象序列化(Object Serialization)API,它使得Java对象能够在不同的JVM之间传递。对象序列化是特别为Java的对象设计的,这就意味着Java程序中的对象可以作为对象参数存取(可序列化的对象必须实现Serializable接口)。结合RMI和对象序列化机制,就可以访问越过本地Java虚拟机边界的对象以及数据。通过RMI,可以调用远程对象的远程方法,而通过Java对象序列化机制可以将对象传递给这些方法。

        最基本的Java模型并没有提供将远程主机上的Java对象看作本地Java程序地址空间一部分的能力,而RMI祢补了这一不足。另外,由于Java与硬件平台无关的特性,无论是同构的系统还是异构的系统,RMI不需移植就可以顺利运行。

       RMI为Java平台的分布式计算提供了一个简单而直接的模型。因为Java的RMI技术是基于Java平台的,所以它将Java平台的安全性和可移植性等优点带到了分布式计算中。RMI大大扩展Java的网络计算能力,它为编写基于分布式对象技术的企业级Internet/Intranet应用提供了强大的系统平台支持。

二、基于socket的网络编程

        当你使用socket进行网络应用开发的时候,一般的思路是“消息驱动逻辑”,即这样的软件系统一般具有以下特点:

       (1) 客户端与服务器端依靠消息进行通讯。

       (2) 客户端或者服务器端都需要一个消息派遣器,将消息投递给具体的massage handler

       (3) 客户端或者服务器端利用massage handler进行逻辑事务处理

三、RMI Vs Sochet

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

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

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

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

      第四、这是最后一点不同,我认为也是比较重要的一点,就是两种方法的性能比较,其往往决定着你将使用那种技术来开发你的应用。以下引用Adrian Reber在Network-programming with RMI文中对TCP和RMI所做的一个比较,其做的实验主要是对两者在网络传输的带宽上作的对比: 在网络上传输2 byte的有效数据,对于TCP而言,总共有478 byte被额外传输,而对于RMI, 1645byte被额外传输。

以下是两者的trace结果:

TCP:

46037 > 12345 [SYN] Seq=801611567 Ack=0 Win=5840 Len=0

12345 > 46037 [SYN, ACK] Seq=266515894 Ack=801611568 Win=10136 Len=0

46037 > 12345 [ACK] Seq=801611568 Ack=266515895 Win=5840 Len=0

12345 > 46037 [PSH, ACK] Seq=266515895 Ack=801611568 Win=10136 Len=1

46037 > 12345 [ACK] Seq=801611568 Ack=266515896 Win=5840 Len=0

12345 > 46037 [FIN, PSH, ACK] Seq=266515896 Ack=801611568 Win=10136 Len=1

46037 > 12345 [RST, ACK] Seq=801611568 Ack=266515898 Win=5840 Len=0

RMI:

42749 > rmiregistry [SYN, ECN, CWR]

Seq=3740552479 Ack=0 Win=32767 Len=0

rmiregistry > 42749 [SYN, ACK, ECN]

Seq=3749262223 Ack=3740552480 Win=32767 Len=0

42749 > rmiregistry [ACK] Seq=3740552480 Ack=3749262224 Win=32767 Len=0

JRMI, Version: 2, StreamProtocol

rmiregistry > 42749 [ACK] Seq=3749262224 Ack=3740552487 Win=32767 Len=0

JRMI, ProtocolAck

42749 > rmiregistry [ACK] Seq=3740552487 Ack=3749262240 Win=32767 Len=0

Continuation

rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552506 Win=32767 Len=0

JRMI, Call

rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552556 Win=32767 Len=0

JRMI, ReturnData

42749 > rmiregistry [ACK] Seq=3740552556 Ack=3749262442 Win=32767 Len=0

JRMI, Ping

JRMI, PingAck

42749 > rmiregistry [ACK] Seq=3740552557 Ack=3749262443 Win=32767 Len=0

JRMI, DgcAck

42749 > rmiregistry [FIN, ACK]

Seq=3740552572 Ack=3749262443 Win=32767 Len=0

rmiregistry > 42749 [FIN, ACK]

Seq=3749262443 Ack=3740552573 Win=32767 Len=0

42749 > rmiregistry [ACK] Seq=3740552573 Ack=3749262444 Win=32767 Len=0

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

四、参考资料:

Network-programming with RMI, by Adrian Reber, URL:

http://42.fht-esslingen.de/~adrian/master/rmi.pdf

0 0
原创粉丝点击