- 浏览: 555572 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (340)
- Spring (4)
- Hibernate (2)
- Linux (34)
- Oracle (145)
- Eclipse (1)
- UML (1)
- HTML&&JAVASCRIPT (11)
- JAVA (33)
- 设计模式 (1)
- 版本控制 (1)
- wrap框架 (3)
- IBATIS (5)
- Ruby (1)
- DWR (1)
- MINA (11)
- JBPM (2)
- 缓存技术 (4)
- 网络 (3)
- 应用服务器 (1)
- GWT (5)
- 杂谈 (2)
- ICE (4)
- XML (2)
- ArcGis (2)
- Flex (8)
- junit单元测试 (1)
- SNMP (1)
- 存储 (1)
- office (1)
- MongoDB (0)
- Greenplum (3)
- 管理点滴 (1)
- C++ (6)
- 网络入门 (3)
- Tomcat (7)
- JMX (0)
- webservice (1)
- Oracle的10046事件 (1)
- Library cache内部机制详解 (1)
- expdp通过dblink来导入 (1)
最新评论
-
yuanliangding:
有没有关于mock的更多知识。
基于mock对象和JUnit框架简化Spring Web组件单元测试 -
saup007:
ssh端口不是22,怎么搞呢?
Greenplum 学习笔记 -
springmvc-freemarker:
java开源项目源码实例下载
Apache上全部JAVA开源项目简介 -
bobbell:
哇塞,你真厉害,整理的非常全面。我是一个java barcod ...
Greenplum 学习笔记 -
wsj55133245513324:
这不是bug,你将日志级别从debug提升到INFO 就好了 ...
Spring,smppapi,apache mina, ssl快速实现安全的smpp(5)
ICE的整体架构
服务器端:
服务器端通常只有一个通信器(Ice::Communicator),通信器包含了一系列的资源:
如线程池、配置属性、对象工厂、日志记录、统计对象、路由器、定位器、插件管理器、对象适配器
在通信器内,包含有一个或更多的对象适配器(Ice::ObjectAdapter),对象适配器负责提供一个或多个传输端点,并且把进入的请求分派到对应的servant中去执行。
具体实现的部分称为servant,它们为客户端发来的调用提供服务。servant向对象适配器注册以后,由对象适配器依据客户请求调用相应方法。
客户端:
客户端直接通过代理进行远程调用,就象本地调用一样简单。
通信器Ice::Communicator
通信器管理着线程池、配置属性、对象工厂、日志记录、统计对象、路由器、定位器、插件管理器、对象适配器。
通信器的几个重要方法:
std::string proxyToString(const Ice::ObjectPrx&) const; Ice::ObjectPrx stringToProxy(const std::string&) const;
这两个方法可以使代理对象和字符串之间互相转换。对于proxyToString方法,你也可以使用代理对象的 ice_toString方法代替(当然,你要确保是非空的代替对象)。
Ice::ObjectPrx propertyToProxy(const std::string&) const;
这个方法根据给定名字的属性配置生成一个代理对象,如果没有对应属性,返回一个空代理。
比如有如下属性:
MyApp.Proxy = ident:tcp -p 5000
我们就可以这样得到它的代理对象:
Ice::ObjectPrx p = communicator->propertyToProxy("MyApp.Proxy");
Ice::Identity stringToIdentity(const std::string&) const; std::string identityToString(const Ice::Identity&) const;
转换字符串到一个对象标识,对象标识的定义如下:
- namespace Ice
- {
- struct Identity
- {
- std::string name;
- std::string category;
- };
- }
当它与字符串相互转换时,对应的字符串形式是:CATEGORY/NAME。比如字符串“Factory/File”, Factory是category,File是name。
category部分可以为空。
Ice::ObjectAdapterPtr createObjectAdapter(const std::string&); Ice::ObjectAdapterPtr createObjectAdapterWithEndpoints( const std::string&, const std::string&);
这两个方法创建新的对象适配器。createObjectAdapter从属性配置中取得端点信息,而 createObjectAdapterWithEndpoints则直接指定端点。
void shutdown();
关闭服务端的Ice运行时库,调用shutdown后,执行过程中的操作仍可正常完成,shutdown不会等待这些操作完成。
void waitForShutdown();
这个方法会挂起发出调用的线程直到通信器关闭为止。
void destroy();
这个方法回收通信器的相关资源,如线程、通信端点及内存资源。在离开main函数之前,必须调用destory。
bool isShutdown() const;
如果shutdown已被调用过,则返回true。
初始化通信器
在建立通信器(Ice::Communicator)期间,Ice运行时会初始化一系列的对象,这些对象一直影响通信器的整个生命周期。并且在建立通信器以后,你不能改变这些对象。所以,如果你想定制这些对象,就必须在建立通信器的过程中定义。
在通信器建立期间,我们可以定义下面这些对象:
- 属性表(property)
- 日志记录器(Logger)
- 统计对象(Stats)
- 原生字符串与宽字符串转换器
- 线程通知钩子
所有上面的对象存放在InitializationData结构中,定义为:
- namespace Ice {
- struct InitializationData {
- PropertiesPtr properties;
- LoggerPtr logger;
- StatsPtr stats;
- StringConverterPtr stringConverter;
- WstringConverterPtr wstringConverter;
- ThreadNotificationPtr threadHook;
- };
- }
这个结构中的所有成员都是智能指针类型,设置好这些成员以后,就可以通过通信器的初始化函数传入这些对象:
- namespace Ice {
- CommunicatorPtr initialize(int&, char*[],
- const InitializationData& = InitializationData());
- CommunicatorPtr initialize(StringSeq&,
- const InitializationData& = InitializationData());
- CommunicatorPtr initialize(
- const InitializationData& = InitializationData());
- }
我们前面使用的Ice::Application也提供了InitializationData的传入途径:
- namespace Ice
- {
- struct Application
- {
- int main(int, char*[]);
- int main(int, char*[], const char*);
- int main(int, char*[], const Ice::InitializationData&);
- int main(const StringSeq&);
- int main(const StringSeq&, const char*);
- int main(const StringSeq&, const Ice::InitializationData&);
- ...
- };
- }
再回头看InitializationData结构:
properties:PropertiesPtr 类型,指定了属性表(property)对象,它就是之前《Ice属性配置》一文中的主角。默认的属性表实现可以解析“Key = Value”这种形式的字符串(包括命令行参数和文件),如果愿意,你可以自己写一个属性表实现,用来解析xml、ini等等。
如果要自己实现,就得完成下面这些接口(每个方法的作用请参考《Ice属性配置》):
- namespace Ice
- {
- class Properties : virtual public Ice::LocalObject
- {
- public:
- virtual std::string getProperty(const std::string&) = 0;
- virtual std::string getPropertyWithDefault(const std::string&,
- const std::string&) = 0;
- virtual Ice::Int getPropertyAsInt(const std::string&) = 0;
- virtual Ice::Int getPropertyAsIntWithDefault(const std::string&,
- Ice::Int) = 0;
- virtual Ice::StringSeq getPropertyAsList(const std::string&) = 0;
- virtual Ice::StringSeq getPropertyAsListWithDefault(const std::string&,
- const Ice::StringSeq&) = 0;
- virtual Ice::PropertyDict getPropertiesForPrefix(const std::string&) = 0;
- virtual void setProperty(const std::string&, const std::string&) = 0;
- virtual Ice::StringSeq getCommandLineOptions() = 0;
- virtual Ice::StringSeq parseCommandLineOptions(const std::string&,
- const Ice::StringSeq&) = 0;
- virtual Ice::StringSeq parseIceCommandLineOptions(const Ice::StringSeq&) = 0;
- virtual void load(const std::string&) = 0;
- virtual Ice::PropertiesPtr clone() = 0;
- };
- };
logger: LoggerPtr类型,这是一个日志记录器接口,它可以记录Ice运行过程中产生的跟踪、警告和错误信息,默认实现是直接向cerr输出。比如作用我们之前的Helloworld的例子,在没开服务端的情况下运行客户端,就看到在控制超台上打印了一串错误信息。
我们可以自己实现这个接口,以控制它的输出方向,它的定义为:
- namespace Ice
- {
- class Logger : virtual public Ice::LocalObject
- {
- public:
- virtual void print(const std::string& msg) = 0;
- virtual void trace(const std::string& category,
- const std::string& msg) = 0;
- virtual void warning(const std::string& msg) = 0;
- virtual void error(const std::string& msg) = 0;
- };
- }
不用说,实现它们是一件很轻松的事情^_^,比如你可以实现这个接口把信息写到一个日志文件里,或者把它写到某个日志服务器上。
stats: StatsPtr类型,当Ice发送或接收到数据时,会向Stats报告发生的字节数,这个接口更加简单:
- namespace Ice
- {
- class Stats : virtual public Ice::LocalObject
- {
- public:
- virtual void bytesSent(const std::string& protocol,
- Ice::Int num) = 0;
- virtual void bytesReceived(const std::string& protocol,
- Ice::Int num) = 0;
- };
- }
stringConverter:BasicStringConverter<char>类型;
wstringConverter:BasicStringConverter<wchar_t>类型;
这两个接口用于本地编码与UTF-8编码之间的转换,Ice系统自带了三套转换系统,默认的UnicodeWstringConverter、Linux/Unix 下使用的IconvStringConverter和Windows 下使用的WindowsStringConverter。
threadHook: ThreadNotificationPtr类型,线程通知钩子,当Ice建立一个新线程后,线程通知钩子就会首先得到“线程启动通知”,在结束线程之前,也能得到“线程结束通知”。
下面是ThreadNotification接口的定义:
- namespace Ice
- {
- class ThreadNotification : public IceUtil::Shared {
- public:
- virtual void start() = 0;
- virtual void stop() = 0;
- };
- }
假如我们在Windows下使用了COM组件的话,就可以使用线程通知钩子在start和stop里调用 CoInitializeEx和CoUninitialize。
代码演示
修改一下Helloworld服务器端代码,实现自定义统计对象(Stats,毕竟它最简单嘛-_-):
- #include <ice/ice.h>
- #include "printer.h"
- using namespace std;
- using namespace Demo;
- struct PrinterImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- cout << s << endl;
- }
- };
- class MyStats : public Ice::Stats {
- public:
- virtual void bytesSent(const string &prot, Ice::Int num)
- {
- cerr << prot << ": sent " << num << "bytes" << endl;
- }
- virtual void bytesReceived(const string &prot, Ice::Int num)
- {
- cerr << prot << ": received " << num << "bytes" << endl;
- }
- };
- class MyApp : public Ice::Application{
- public:
- virtual int run(int n, char* v[]){
- Ice::CommunicatorPtr& ic = communicator();
- ic->getProperties()->parseCommandLineOptions(
- "SimplePrinterAdapter", Ice::argsToStringSeq(n,v));
- Ice::ObjectAdapterPtr adapter
- = ic->createObjectAdapter("SimplePrinterAdapter");
- Ice::ObjectPtr object = new PrinterImp;
- adapter->add(object, ic->stringToIdentity("SimplePrinter"));
- adapter->activate();
- ic->waitForShutdown();
- return 0;
- }
- };
- int main(int argc, char* argv[])
- {
- MyApp app;
- Ice::InitializationData id;
- id.stats = new MyStats;
- return app.main(argc, argv, id);
- }
编译运行这个演示代码,然后执行客户端,可以看到打印出的接收到发送字符数。
tcp: send 14bytes tcp: received 14bytes tcp: received 52bytes tcp: send 26bytes tcp: received 14bytes tcp: received 53bytes Hello World! tcp: send 25bytes tcp: received 14bytes
对象适配器(Ice::ObjectAdapter)
对象适配器负责提供一个或多个传输端点,并且把进入的请求分派到对应的servant中去执行。它的定义以及主要方法有:
- namespace Ice
- {
- struct ObjectAdapter : public LocalObject
- {
- // 返回适配器的名字(由Communicator::createObjectAdapter输入)
- std::string getName() const;
- // 返回创建并拥有应适配器的通信器
- Ice::CommunicatorPtr getCommunicator() const;
- // 激活处于hold状态的适配器。
- void activate();
- // 要求适配器进入hold状态,并马上返回
- void hold();
- // 等待直到适配器进入hold状态
- void waitForHold();
- // 要求适配器进入无效状态,一旦进入无效状态,就无法再次激活它,与该适配器关联的servant将会被销毁。
- void deactivate();
- // 等待直到适配器进入无效状态
- void waitForDeactivate();
- // 如果适配器处于无效状态,返回true
- bool isDeactivated() const;
- // 使适配器处于无效状态,并且释放所有的资源(包括适配器名)
- void destroy();
- // 使用指定的标识把servant注册到适配器中,返回该servant的代理
- Ice::ObjectPrx add(const Ice::ObjectPtr&, const Ice::Identity&);
- // 使用随机生成的UUID作为标识把servant注册到适配器中,返回该servant的代理
- Ice::ObjectPrx addWithUUID(const Ice::ObjectPtr&);
- // 从适配器中移除对应的servant
- Ice::ObjectPtr remove(const Ice::Identity&);
- // 查找对应标识的servant
- Ice::ObjectPtr find(const Ice::Identity&) const;
- // 查找代理对应的servant
- Ice::ObjectPtr findByProxy(const Ice::ObjectPrx&) const;
- // 把一个 Servant Locator 添加到这个对象适配器中。
- void addServantLocator(const Ice::ServantLocatorPtr&, const std::string&);
- // 查找一个已经安装到这个对象适配器中的 Servant Locator。
- Ice::ServantLocatorPtr findServantLocator(const std::string&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的代理
- Ice::ObjectPrx createProxy(const Ice::Identity&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的 " 直接代理 "。
- // 直接代理总是包含有当前的适配器端点。
- Ice::ObjectPrx createDirectProxy(const Ice::Identity&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的 " 间接代理 "。
- // 间接代理只包含对象的标识和适配器名,通过定位器服务来得到服务器地址
- Ice::ObjectPrx createIndirectProxy(const Ice::Identity&) const;
- // 为这个对象适配器设置一个 Ice 定位器
- void setLocator(const Ice::LocatorPrx&);
- // 重新读入适配器的PublicshedEndpoints属性并更新内部的可用网络接口列表
- void refreshPublishedEndpoints();
- };
- }
Servant定位器
除直接向对象适配器注册servant以外,Ice允许我们向对象适配器提供一个Servant定位器。
有了Servant定位器以后,对象适配器得到一次请求时首先查找已注册的servant,如果没找到对应的servant,就会请求 Servant定位器提供servant。
采用这种简单的机制,我们的服务器能够让我们访问数量不限的servant:服务器不必为每一个现有的Ice对象实例化一个单独的 servant。
下面是Servant定位器的接口,我们必须自己实现这个接口:
- namespace Ice
- {
- class ServantLocator : virtual public Ice::LocalObject
- {
- // 只要有请求到达,而且适配器没有提供注册的条目,Ice就会调用locate。
- // locate的实现(由你在派生类中提供)应该返回一个能够处理该请求的 servant。
- // 通过cookie参数,你可以传入一个自定义指针数据,对象适配器并不在乎这个对象的内容
- // 当Ice 调用finished 时,会把你从locate 返回的cookie传回给你。
- virtual Ice::ObjectPtr locate(const Ice::Current& curr,
- Ice::LocalObjectPtr& cookie) = 0;
- // 一旦请求完成,Ice就会调用finished。
- // 把完成了操作的servant、该请求的Current 对象
- // 以及locate在一开始创建的 cookie 传给它。
- virtual void finished(const Ice::Current& curr,
- const Ice::ObjectPtr& obj, const Ice::LocalObjectPtr& cookie) = 0;
- // 当servant定位器所属的对象适配器无效时,Ice会调用deactivate方法。
- virtual void deactivate(const std::string&) = 0;
- };
- }
实现了ServantLocator后,通过对象适配器的addServantLocator方法注册到该适配器中。
在上面的接口中,有一个Ice::Current结构类型的参数,通过它,我们就可以访问“正在执行的请求”和“服务器中的操作的实现”等信息,Ice::Current的定义如下:
- namespace Ice
- {
- struct Current
- {
- // 负责分派当前请求的对象适配器
- Ice::ObjectAdapterPtr adapter;
- //
- Ice::ConnectionPtr con;
- // 当前请求的对象标识
- Ice::Identity id;
- // 请求的 facet
- std::string facet;
- // 正在被调用的操作的名字。
- std::string operation;
- // 操作的调用模式(Normal、Idempotent,或Nonmutating)
- Ice::OperationMode mode;
- // 这个调用的当前上下文,这是一个std::map类型的数据
- // 使用它就允许把数量不限的参数从客户发往服务器
- Ice::Context ctx;
- //
- Ice::Int requestId;
- };
- }
利用Ice::Current的id成员,我们可以得到所请求的对象标识,从而决定生产某个具体的Servant;使用ctx成员,我们还可以从客户端发送数据不限的“键值-数值”对到服务器中,实现灵活控制(甚至连方法参数都可以不用了,全部用ctx转送就行)。
例:向原HelloWorld 版服务器加入Servant定位器代码,当请求的标识的category为"Loc"时,由定位器返回对应的 servant。
服务器端
- #include <ice/ice.h>
- #include "printer.h"
- using namespace std;
- using namespace Demo;
- // 原打印版本
- struct PrinterImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- cout << s << endl;
- }
- };
- // OutputDebugString版本
- struct DbgOutputImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- ::OutputDebugStringA(s.c_str());
- }
- };
- // MessageBox版本
- struct MsgboxImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- ::MessageBoxA(NULL,s.c_str(),NULL,MB_OK);
- }
- };
- struct MyLocator : Ice::ServantLocator{
- virtual Ice::ObjectPtr locate(const Ice::Current& curr,
- Ice::LocalObjectPtr& cookie)
- {
- if(curr.id.name == "Dbg")
- return Ice::ObjectPtr(new DbgOutputImp);
- else if(curr.id.name == "Msg")
- return Ice::ObjectPtr(new MsgboxImp);
- else if(curr.id.name == "SimplePrinter")
- return Ice::ObjectPtr(new PrinterImp);
- else
- return NULL;
- }
- virtual void finished(const Ice::Current& curr,
- const Ice::ObjectPtr& obj, const Ice::LocalObjectPtr&)
- {
- }
- virtual void deactivate(const std::string& category)
- {
- }
- };
- class MyApp : public Ice::Application{
- public:
- virtual int run(int n, char* v[]){
- Ice::CommunicatorPtr& ic = communicator();
- ic->getProperties()->parseCommandLineOptions(
- "SimplePrinterAdapter", Ice::argsToStringSeq(n,v));
- Ice::ObjectAdapterPtr adapter
- = ic->createObjectAdapter("SimplePrinterAdapter");
- Ice::ObjectPtr object = new PrinterImp;
- adapter->add(object, ic->stringToIdentity("SimplePrinter"));
- // 注册MyLocator定位器,负责返回category为"Loc"的相应servant。
- adapter->addServantLocator(Ice::ServantLocatorPtr(new MyLocator),"Loc");
- adapter->activate();
- ic->waitForShutdown();
- return 0;
- }
- };
- int main(int argc, char* argv[])
- {
- MyApp app;
- return app.main(argc, argv);
- }
客户端代码与《ICE属性配置》中的代码相同,客户端命令行参数为
--MyProp.Printer="Loc/Msg:tcp -p 10000"
服务器端将会使用对话框显示“HelloWorld”。
对象代理(Object Proxy)
在客户端,我们使用对象代理进行远程调用,就如它们就在本地一样。但有时,网络问题还是要考虑的,于是Ice的对象代理提供了几个包装方法,以支持一些网络特性:
ice_timeout方法,声明为:Ice::ObjectPrx ice_timeout(int) const;返回一个超时代理,当在指定的时间(单位毫秒)内没有得到服务器端响应时,操作终止并抛出Ice::TimeoutException异常。
示例代码:
- Filesystem::FilePrx myFile = ...;
- FileSystem::FilePrx timeoutFile
- = FileSystem::FilePrx::uncheckedCast(
- myFile->ice_timeout(5000));
- try {
- Lines text = timeoutFile->read(); // Read with timeout
- } catch(const Ice::TimeoutException &) {
- cerr << "invocation timed out" << endl;
- }
- Lines text = myFile->read(); // Read without timeout
ice_oneway方法,声明为:Ice::ObjectPrx ice_oneway() const;返回一个单向调用代理。只要数据从本地端口发送出去,单向调用代理就认为已经调用成功。这意味着,单向调用是不可靠的:它可能根本没有发送出去 (例如,因为网络故障) ,也可能没有被服务器接受(例如,因为目标对象不存在)。好处是由于不用等服务端回复,能带来很大的效率提升。
示例代码:
- Ice::ObjectPrxo=communicator->stringToProxy(/* ... */);
- // Get a oneway proxy.
- Ice::ObjectPrx oneway = o->ice_oneway();
- // Down-cast to actual type.
- PersonPrx onewayPerson = PersonPrx::uncheckedCast(oneway);
- // Invoke an operation as oneway.
- try {
- onewayPerson->someOp();
- } catch (const Ice::TwowayOnlyException &) {
- cerr << "someOp() is not oneway" << endl;
- }
ice_datagram方法,声明为:Ice::ObjectPrx ice_datagram() const;返回数据报代理,它使用UDP传输机制,并且和单向调用代理一样,不会得到服务器端的答复,而且还有可能UDP包重复和不按次序到达服务端。
示例代码:
- Ice::ObjectPrxo=communicator->stringToProxy(/* ... */);
- // Get a datagram proxy.
- //
- Ice::ObjectPrx datagram;
- try {
- datagram = o->ice_datagram();
- } catch (const Ice::NoEndPointException &) {
- cerr << "No endpoint for datagram invocations" << endl;
- }
- // Down-cast to actual type.
- //
- PersonPrx datagramPerson = PersonPrx::uncheckedCast(datagram);
- // Invoke an operation as a datagram.
- //
- try {
- datagramPerson->someOp();
- } catch (const Ice::TwowayOnlyException &) {
- cerr << "someOp() is not oneway" << endl;
- }
批量调用代理:
Ice::ObjectPrx ice_batchOneway() const; Ice::ObjectPrx ice_batchDatagram() const; void ice_flushBatchRequests();
为了提供网络效率,对于单向调用,可以考虑把多个调用打包一起送往服务器,Ice对象代理提供了ice_batchOneway和ice_batchDatagram方法返回对应的批调用代理,使用这种代理时呼叫信息不会马上发出,而是等到调用ice_flushBatchRequests以后才一次性发出。
示例代码:
- Ice::ObjectPrx base = ic->stringToProxy(s);
- PrinterPrx printer = PrinterPrx::uncheckedCast(base->ice_batchOneway());
- if(!printer) throw "Invalid Proxy!";
- printer->printString("Hello");
- printer->printString("World");
- printer->ice_flushBatchRequests();
相关推荐
4. **预处理与后处理**:为了获得更好的效果,ICE可能在对比度增强前后加入其他预处理和后处理步骤,如去除噪声、边缘保护等。ice.m中可能包含这些辅助函数,确保增强过程不会引入新的问题。 5. **可视化与评估**:...
Ice的核心理念是将复杂的分布式系统设计和实现简化为更简单、更直观的过程。它通过抽象掉底层网络细节,如协议栈、序列化/反序列化过程以及错误处理机制,使开发者能够专注于业务逻辑的编写。这种设计使得Ice在多个...
2. **代理模式**:通过代理模式,Ice可以隐藏底层网络细节,便于服务的动态发现和替换。 3. **多线程支持**:Ice支持多线程编程,允许并发处理多个请求,提高了系统的并行处理能力。 4. **异步调用**:除了同步...
### 分布式编程与ICE 3.3.1:关键知识点概述 #### 一、ICE 3.3.1 概览 - **版本信息**:文档为ICE 3.3.1版本,...通过对该版本的深入了解,可以帮助开发者更好地利用ICE的强大功能,解决实际项目中的复杂通信问题。
本文将围绕ICE 3.4.1版本的源码展开,深入探讨其设计原理、核心组件以及实现细节。 1. **ICE概述** ICE提供了一种中间件解决方案,支持C++、Java、Python等多种语言,并且通过其“ Slice”接口定义语言,实现跨...
8. **社区支持**:ICE999 WZ的成功也离不开用户的社区支持,通过交流和分享,用户可以发现更多工具的使用技巧,同时也能反馈问题,推动工具的持续改进。 由于压缩包子文件的文件名称列表只给出了"ICE999",无法提供...
1. **Interpreted Ice概述**:Interpreted Ice是一种增强型开发环境,它在原有的Ice框架基础上添加了更多高级特性,如动态编译、即时运行等。 2. **动态编译技术**:Interpreted Ice支持动态编译,即开发者可以在不...
2. **多语言支持**: ICE支持多种编程语言,允许不同语言的组件无缝交互。这通过ICE的编译器实现,它可以将接口定义转化为各种目标语言的代码。 3. **透明性**: ICE提供了透明的网络分布,使得开发者无需关心对象是...
而Java Socket则需要更多的代码来实现相同的功能,尤其是错误处理和协议细节的处理。 3. **安全性**:两者都支持加密通信,但Ice内置的安全特性如身份验证和授权可能更为强大,能简化安全管理。 4. **扩展性**:...
ICE 3.3版本是其一个重要的更新,引入了更多的特性和优化,以提升开发效率和系统性能。 在安装ICE 3.3时,首先需要从官方网站或者指定的链接下载对应平台的安装包。安装过程中,需要注意选择正确的操作系统版本,并...
Ice允许开发者在不同的操作系统和硬件平台上部署应用程序而无需担心底层细节。这种特性使得基于Ice构建的应用能够轻松跨越多个异构环境进行通信。 #### 2. 语言独立 Ice支持多种流行的编程语言,并通过统一的API...
为了更深入地学习ICE,你可以参考官方文档、在线教程、示例代码,以及提供的博客链接,通过实践和阅读源代码来提升你的技能。同时,加入相关的开发者社区或论坛,与其他开发者交流,解决遇到的问题,将加速你的学习...
通过对ICE 3.7源码的深入研究,开发者可以更好地理解分布式系统的底层工作原理,从而在实际项目中更高效地利用ICE的功能,优化性能,解决复杂问题。对于想要提升分布式系统设计和实现能力的工程师来说,ICE 3.7的...
3. **学习曲线**:相比于ICE,Java Socket的学习曲线较陡峭,需要开发者自己处理更多的细节。 4. **序列化和反序列化**:Java Socket不自带序列化机制,开发者需要手动实现或者使用第三方库如Protocol Buffers...
10. **社区资源**:标签中提到了"jb51.net"和"脚本之家",这些都是程序员常用的资源网站,可能包含了更多关于ICE和C++的教程、问答和工具,读者可以在这里找到额外的支持和学习资料。 此外,压缩包中的"PDF阅读器...
通过对文档标题、描述、标签和部分核心内容的解读,我们可以了解到Ice中间件是设计用来简化分布式编程任务的工具,它提供了一个框架,使得开发者能够更专注于业务逻辑的实现,而不是底层网络通信的细节。此外,Ice的...