一、ICE简介:

1、ICE是什么?
 ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,使我们能够以最小的代价构建分布式应用程序。ICE使我们专注于应用逻辑的开发,它来处理所有底层的网络接口编程,这样我们就不用去考虑这样的细节:打开网络连接、网络数据传输的序列化与反序列化、连接失败的尝试次数等。

2、为什么会有ICE? 
 ICE是分布式应用的一种比较好的解决方案,虽然现在也有一些比较流行的分布式应用解决方案,如微软的.NET(以及原来的DCOM)、CORBA及WEB SERVICE等,但是这些面向对象的中间件都存在一些不足:
 .NET是微软产品,只面向WINDOWS系统,而实际的情况是在当前的网络环境下,不同的计算机会运行不同的系统,如LINUX上面就不可能使用.NET;
 CORBA虽然在统一标准方面做了很多的工作,但是不同的供应商实现之间还是缺乏互操作性,并且目前还没有一家供应商可以针对所有的异种环境提供所有的实现支持,且CORBA的实现比较复杂,学习及实施的成本都会比较高;
 WEB SERVICE最要命的缺点就是他的性能问题,对于要求比较高的行业是很少会考虑WEB SERVICE的。
 ICE的产生就是源于.NET、CORBA及WEB SERVICE这些中间件的不足,它可以支持不同的系统,如WINDOWS、LINUX等,也可以支持在多种开发语言上使用,如C++、C、JAVA、RUBY、PYTHON、VB等,服务端可以是上面提到的任何一种语言实现的,客户端也可以根据自己的实际情况选择不同的语言实现,如服务端采用C语言实现,而客户端采用JAVA语言实现,底层的通讯逻辑通过ICE的封装实现,我们只需要关注业务逻辑。

3、ICE是如何工作的?
 Ice 是一种面向对象的中间件平台,这意味着 Ice为构建面向对象的客户-服务器应用提供了工具、API 和库支持。要与Ice持有的对象进行通信,客户端必须持有这个对象的代理(与CORBA的引用是相同的意思),这里的代理指的是这个对象的实例,ICE在运行时会定位到这个对象,然后寻找或激活它,再把In参数传给远程对象,再通过Out参数获取返回结果。
 这里提到的代理又分为直接代理和间接代理,直接代理其内部保存有某个对象的标识,以及它的服务器的运行地址;间接代理指的是其内部保存有某个对象的标识,以及对象适配器名(object adapter name),间接代理没有包含寻址信息,为了正确地定位服务器,客户端在运行时会使用代理内部的对象适配器名,将其传给某个定位器服务,比如IcePack服务,然后,定位器会把适配器名当作关键字,在含有服务器地址的表中进行查找,把当前的服务器地址返回给客户,客户端 run time现在知道了怎样联系服务器,就会像平常一样分派 (dispatch)客户请求。
 ICE可以保证在任何的网络环境或者操作系统下,成功的调用只有一次,它在运行时会尽力的定位到远程服务器,在连接失败的情况下会做尝试性重复性连接,确实连不上的情况会给用户以提示。
 客户端在调用服务端的方法时,可以采取同步或异步的方式实现,同步调用就相当于调用自己本地的方法一样,其它行为会被阻塞;异步调用是非常有用的调用方式,如服务端需要准备的数据来自于其它异步接口,这个时候客户端就不需要等待,待服务端数据准备充份后,以消息的方式通知客户端,服务端就可以去干其它的事情了,而客户端也可以到服务端获取数据了。
 
4、ICE调用模式
 ICE采用的网络协议有TCP、UDP以及SSL三 种,不同于WebService,ICE在调用模式上有好几种选择方案,并且每种方案正对不同的网络协议的特性做了相应的选择。
 Oneway(单向调用):客户端只需将调用注册到本地传输缓冲区(Local Transport Buffers)后就立即返回,不会等待调用结果的返回,不对调用结果负责。
 Twoway(双向调用):最通用的模式,同步方法调用模式,只能用TCP或SSL协议。
 Datagram(数据报):类似于Oneway调用,不同的是 Datagram调用只能采用UDP协议而且只能调用无返回值和无输出参数的方法。
 BatchOneway(批量单向调用):先将调用存 在调用缓冲区里面,到达一定限额后自动批量发送所有请求(也可手动刷除缓冲区)。
 BatchDatagram(批量数据报):与上类似。
 不同的调用模式其实对应着不动的业务,对于大部分的有返回值的或需要实时响应的方法,我们可能都采用Twoway方式调用,对于一些无需返回值或 者不依赖返回值的业务,我们可以用Oneway或者BatchOneway方式,例如消息通知;剩下的Datagram和BatchDatagram方式 一般用在无返回值且不做可靠性检查的业务上,例如日志。

5、客户端与服务端的结构
 
 这个图示显示了使用ICE做为中间件平台,客户端及服务端的应用都是由应用代码及ICE的库代码混合组成的。
 客户应用及服务器应用分别对应用的是客户端与服务端。
 代理是根据SLICE定义的ice文件实现,它提供了一个向下调用的接口,提供了数据的序列化与反序化。
 ICE的核心部份,提供了客户端与服务端的网络连接等核心通信功能,以及其它的网络通信功能的实现及可能的问题的处理,让我们在编写应用代码的时候不必要去关注这一块,而专注于应用功能的实现。

二、ICE的安装:

第一步,基于Windows下的安装,所以下载windows版的Ice,官网最新版本是Ice3.4.2:
http://www.zeroc.com/download/Ice/3.4/Ice-3.4.2.msi
       第二步,安装Ice:
常规安装即可,可以选择安装目录,本次安装是在D:\Ice
      第三步,设置Ice的环境变量:
主要有环境变量需要设置:path、classpath、ICE_HOME
例如:
path:D:\Ice\bin;
classpath:D:\Ice\lib\Ice.jar;D:\Ice\lib\Freeze.jar;D:\Ice\lib\db.jar;
ICE_HOME:D:\Ice
      第四步,检验:
在命令行中输入:icegridnode --version 
如果现实当前安装的ice版本号,那么就说明安装成功。

三、C++示例:

1、服务端:

a、添加一个名为Client的win32控制台应用程序的空白项目。

b、在属性页配置属性->C/C++->常规->附加包含目录加入$(ICE_HOME)\include;

c、在属性页配置属性->链接器->常规->附加依赖项加入$(ICE_HOME)\lib;

d、在属性页配置属性->链接器->输入->附加依赖项加入加入iced.lib和iceutild.lib,也可以直接用$(ICE_HOME)\lib。但是这一步以上两种加入都会出错,错误为:LINK
: fatal error LNK1104: 无法打开文件“C :\Program.obj”;所以最好是在工程里直接将那两个库添加进工程来。e、新增一个Caculator.ice文件。用记事本来写即可以:

module
MCal
{
     //定义ICE接口,映射为C++里同名的一个类(纯虚类,因此不能实例化,必须继承并重载类中的 相应方法)
    interface Cal
    {
//定义接口里的操作,映射为C++里同名的一个纯虚拟方法
        int add(int num1,int num2);
        int sub(int num1,int num2);
    };
};

f、编译Caculator.ice会生成Caculator.h
和Cacultor.cpp两个文件。 编译方法一:打开cmd,输入slice2cpp Caculator.ice的路径 ,如slice2cpp D:\TestIce\TestIce\ Caculator.ice。或许在你建立的工程中找不到这两个文件,搜寻一下,看看在哪,然后将这两个文件 放在Caculator.ice的目录下。

g、Caculator.ice编译成功后,建立服务器端CaculatorServer.cpp,type.h

type.h文件:

#ifndef _TYPE_H
#define _TYPE_H
#pragma once
#include "Calculate.h"
using namespace std;
using namespace MCal;
class CalI:public Cal
{
public:
CalI();
~CalI();
virtual int add(int num1,int num2,const Ice::Current&);
virtual int sub(int num1,int num2,const Ice::Current&);
private:
int num1d;
int num2d;
};

#endif

CaculatorServer.cpp文件:

// **********************************************************************
// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.

// This copy of Ice is licensed to you under the terms described in the

// ICE_LICENSE file included in this distribution.
// **********************************************************************
// Ice version 3.4.2

// <auto-generated>

// Generated from file `Calculate.ice'

// Warning: do not edit this file.
// </auto-generated>

#include "Calculate.h"
#include <Ice/LocalException.h>
#include <Ice/ObjectFactory.h>
#include <Ice/BasicStream.h>
#include <IceUtil/Iterator.h>

#ifndef ICE_IGNORE_VERSION
#   if ICE_INT_VERSION / 100 != 304
#       error Ice version mismatch!
#   endif
#   if ICE_INT_VERSION % 100 > 50
#       error Beta header file detected
#   endif
#   if ICE_INT_VERSION % 100 < 2
#       error Ice patch level mismatch!
#   endif
#endif

static const ::std::string __MCal__Cal__add_name = "add";
static const ::std::string __MCal__Cal__sub_name = "sub";
::Ice::Object* IceInternal::upCast(::MCal::Cal* p) { return p; }
::IceProxy::Ice::Object* IceInternal::upCast(::IceProxy::MCal::Cal* p) { return p; }

voidMCal::__read(::IceInternal::BasicStream*
__is, ::MCal::CalPrx& v)
{
    ::Ice::ObjectPrx proxy;
    __is->read(proxy);
    if(!proxy)
    {
        v = 0;
    }
    else
    {
        v = new ::IceProxy::MCal::Cal;
        v->__copyFrom(proxy);
    }
}

::Ice::IntIceProxy::MCal::Cal::add(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __ctx)
{
    int __cnt = 0;
    while(true)
    {
        ::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase;
        try
        {
            __checkTwowayOnly(__MCal__Cal__add_name);
            __delBase = __getDelegate(false);
            ::IceDelegate::MCal::Cal* __del = dynamic_cast< ::IceDelegate::MCal::Cal*>(__delBase.get());
            return __del->add(num1, num2, __ctx);
        }
        catch(const ::IceInternal::LocalExceptionWrapper& __ex)
        {
            __handleExceptionWrapper(__delBase, __ex);
        }
        catch(const ::Ice::LocalException& __ex)
        {
            __handleException(__delBase, __ex, true, __cnt);
        }
    }
}

::Ice::AsyncResultPtrIceProxy::MCal::Cal::begin_add(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __ctx, const ::IceInternal::CallbackBasePtr& __del, const ::Ice::LocalObjectPtr& __cookie)

{
    __checkAsyncTwowayOnly(__MCal__Cal__add_name);

::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, __MCal__Cal__add_name, __del, __cookie);

try
    {
        __result->__prepare(__MCal__Cal__add_name, ::Ice::Normal, __ctx);
        ::IceInternal::BasicStream* __os = __result->__getOs();
        __os->write(num1);
        __os->write(num2);
        __os->endWriteEncaps();
        __result->__send(true);
    }

catch(const ::Ice::LocalException& __ex)
    {
        __result->__exceptionAsync(__ex);
    }

return __result;
}

::Ice::IntIceProxy::MCal::Cal::end_add(const
::Ice::AsyncResultPtr& __result)
{
    ::Ice::AsyncResult::__check(__result, this, __MCal__Cal__add_name);
    ::Ice::Int __ret;
    if(!__result->__wait())
    {
        try
        {
            __result->__throwUserException();
        }
        catch(const ::Ice::UserException& __ex)
        {
            throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());
        }
    }
    ::IceInternal::BasicStream* __is = __result->__getIs();
    __is->startReadEncaps();
    __is->read(__ret);
    __is->endReadEncaps();
    return __ret;
}

::Ice::IntIceProxy::MCal::Cal::sub(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __ctx)
{
    int __cnt = 0;
    while(true)
    {
        ::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase;
        try
        {
            __checkTwowayOnly(__MCal__Cal__sub_name);
            __delBase = __getDelegate(false);
            ::IceDelegate::MCal::Cal* __del = dynamic_cast< ::IceDelegate::MCal::Cal*>(__delBase.get());
            return __del->sub(num1, num2, __ctx);
        }
        catch(const ::IceInternal::LocalExceptionWrapper& __ex)
        {
            __handleExceptionWrapper(__delBase, __ex);
        }
        catch(const ::Ice::LocalException& __ex)
        {
            __handleException(__delBase, __ex, true, __cnt);
        }
    }
}

::Ice::AsyncResultPtrIceProxy::MCal::Cal::begin_sub(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __ctx, const ::IceInternal::CallbackBasePtr& __del, const ::Ice::LocalObjectPtr& __cookie)
{
    __checkAsyncTwowayOnly(__MCal__Cal__sub_name);
    ::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, __MCal__Cal__sub_name, __del, __cookie);
    try
    {
        __result->__prepare(__MCal__Cal__sub_name, ::Ice::Normal, __ctx);
        ::IceInternal::BasicStream* __os = __result->__getOs();
        __os->write(num1);
        __os->write(num2);
        __os->endWriteEncaps();
        __result->__send(true);
    }
    catch(const ::Ice::LocalException& __ex)
    {
        __result->__exceptionAsync(__ex);
    }
    return __result;
}

::Ice::IntIceProxy::MCal::Cal::end_sub(const
::Ice::AsyncResultPtr& __result)
{
    ::Ice::AsyncResult::__check(__result, this, __MCal__Cal__sub_name);
    ::Ice::Int __ret;
    if(!__result->__wait())
    {
        try
        {
            __result->__throwUserException();
        }
        catch(const ::Ice::UserException& __ex)
        {
            throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());
        }
    }

::IceInternal::BasicStream* __is = __result->__getIs();
    __is->startReadEncaps();
    __is->read(__ret);
    __is->endReadEncaps();
    return __ret;
}

const ::std::string&IceProxy::MCal::Cal::ice_staticId()
{
    return ::MCal::Cal::ice_staticId();
}

::IceInternal::Handle< ::IceDelegateM::Ice::Object>IceProxy::MCal::Cal::__createDelegateM()
{
    return ::IceInternal::Handle< ::IceDelegateM::Ice::Object>(new ::IceDelegateM::MCal::Cal);
}

::IceInternal::Handle< ::IceDelegateD::Ice::Object>IceProxy::MCal::Cal::__createDelegateD()
{
    return ::IceInternal::Handle< ::IceDelegateD::Ice::Object>(new ::IceDelegateD::MCal::Cal);
}
::IceProxy::Ice::Object*IceProxy::MCal::Cal::__newInstance()
const
{
    return new Cal;
}

::Ice::IntIceDelegateM::MCal::Cal::add(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
    ::IceInternal::Outgoing __og(__handler.get(), __MCal__Cal__add_name, ::Ice::Normal, __context);
    try
    {
        ::IceInternal::BasicStream* __os = __og.os();
        __os->write(num1);
        __os->write(num2);
    }
    catch(const ::Ice::LocalException& __ex)
    {
        __og.abort(__ex);
    }
    bool __ok = __og.invoke();
    ::Ice::Int __ret;
    try
    {
        if(!__ok)
        {
            try
            {
                __og.throwUserException();
            }
            catch(const ::Ice::UserException& __ex)
            {
                ::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_name());
                throw __uue;
            }
        }
        ::IceInternal::BasicStream* __is = __og.is();
        __is->startReadEncaps();
        __is->read(__ret);
        __is->endReadEncaps();
        return __ret;
    }

catch(const ::Ice::LocalException& __ex)
    {
        throw ::IceInternal::LocalExceptionWrapper(__ex, false);
    }
}

::Ice::IntIceDelegateM::MCal::Cal::sub(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __context)

{
    ::IceInternal::Outgoing __og(__handler.get(), __MCal__Cal__sub_name, ::Ice::Normal, __context);
    try
    {
        ::IceInternal::BasicStream* __os = __og.os();
        __os->write(num1);
        __os->write(num2);
    }
    catch(const ::Ice::LocalException& __ex)
    {
        __og.abort(__ex);
    }
    bool __ok = __og.invoke();
    ::Ice::Int __ret;
    try
    {
        if(!__ok)
        {
            try
            {
                __og.throwUserException();
            }
            catch(const ::Ice::UserException& __ex)
            {
                ::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_name());
                throw __uue;
            }
        }
        ::IceInternal::BasicStream* __is = __og.is();
        __is->startReadEncaps();
        __is->read(__ret);
        __is->endReadEncaps();
        return __ret;
    }
    catch(const ::Ice::LocalException& __ex)
    {
        throw ::IceInternal::LocalExceptionWrapper(__ex, false);
    }
}

::Ice::IntIceDelegateD::MCal::Cal::add(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
    class _DirectI : public ::IceInternal::Direct
    {
    public:
        _DirectI(::Ice::Int& __result, ::Ice::Int num1, ::Ice::Int num2, const ::Ice::Current& __current) : 
        ::IceInternal::Direct(__current),
        _result(__result),
         _m_num1(num1),
         _m_num2(num2)
        {
        }
       virtual ::Ice::DispatchStatus
        run(::Ice::Object* object)
        {
            ::MCal::Cal* servant = dynamic_cast< ::MCal::Cal*>(object);
            if(!servant)
            {
                throw ::Ice::OperationNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation);
            }
            _result = servant->add(_m_num1, _m_num2, _current);
            return ::Ice::DispatchOK;
        }
     private:
   
        ::Ice::Int& _result;
        ::Ice::Int _m_num1;
        ::Ice::Int _m_num2;
    };
  ::Ice::Current __current;
    __initCurrent(__current, __MCal__Cal__add_name, ::Ice::Normal, __context);
    ::Ice::Int __result;
    try
    {
        _DirectI __direct(__result, num1, num2, __current);
        try
        {
            __direct.servant()->__collocDispatch(__direct);
        }
        catch(...)
        {
            __direct.destroy();
            throw;
        }
        __direct.destroy();
    }
    catch(const ::Ice::SystemException&)
    {
        throw;
    }
    catch(const ::IceInternal::LocalExceptionWrapper&)
    {
        throw;
    }
    catch(const ::std::exception& __ex)
    {
        ::IceInternal::LocalExceptionWrapper::throwWrapper(__ex);
    }
    catch(...)
    {
        throw ::IceInternal::LocalExceptionWrapper(::Ice::UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
    }
    return __result;
}

::Ice::IntIceDelegateD::MCal::Cal::sub(::Ice::Int
num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
    class _DirectI : public ::IceInternal::Direct
    {
    public:
        _DirectI(::Ice::Int& __result, ::Ice::Int num1, ::Ice::Int num2, const ::Ice::Current& __current) : 
        ::IceInternal::Direct(__current),
        _result(__result),
        _m_num1(num1),
        _m_num2(num2)
        {
        }
        virtual ::Ice::DispatchStatus
        run(::Ice::Object* object)
        {
            ::MCal::Cal* servant = dynamic_cast< ::MCal::Cal*>(object);
            if(!servant)
            {
                throw ::Ice::OperationNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation);
            }
            _result = servant->sub(_m_num1, _m_num2, _current);
            return ::Ice::DispatchOK;
        }
    private:

::Ice::Int& _result;
        ::Ice::Int _m_num1;
        ::Ice::Int _m_num2;
    };

::Ice::Current __current;
    __initCurrent(__current, __MCal__Cal__sub_name, ::Ice::Normal, __context);
    ::Ice::Int __result;
    try
    {
        _DirectI __direct(__result, num1, num2, __current);
        try
        {
            __direct.servant()->__collocDispatch(__direct);
        }
        catch(...)
        {
            __direct.destroy();
            throw;
        }
        __direct.destroy();
    }
    catch(const ::Ice::SystemException&)
    {
        throw;
    }
    catch(const ::IceInternal::LocalExceptionWrapper&)
    {
        throw;
    }
    catch(const ::std::exception& __ex)
    {
        ::IceInternal::LocalExceptionWrapper::throwWrapper(__ex);
    }
    catch(...)
    {
        throw ::IceInternal::LocalExceptionWrapper(::Ice::UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
    }
    return __result;
}

::Ice::ObjectPtrMCal::Cal::ice_clone()
const
{
    throw ::Ice::CloneNotImplementedException(__FILE__, __LINE__);
    return 0; // to avoid a warning with some compilers
}
static const ::std::string __MCal__Cal_ids[2] =
{
    "::Ice::Object",
    "::MCal::Cal"
};

boolMCal::Cal::ice_isA(const ::std::string&
_s, const ::Ice::Current&) const
{
    return ::std::binary_search(__MCal__Cal_ids, __MCal__Cal_ids + 2, _s);
}

::std::vector< ::std::string>MCal::Cal::ice_ids(const
::Ice::Current&) const
{
    return ::std::vector< ::std::string>(&__MCal__Cal_ids[0], &__MCal__Cal_ids[2]);
}
const ::std::string&MCal::Cal::ice_id(const
::Ice::Current&) const
{
    return __MCal__Cal_ids[1];
}

const ::std::string&MCal::Cal::ice_staticId()
{
    return __MCal__Cal_ids[1];
}
::Ice::DispatchStatusMCal::Cal::___add(::IceInternal::Incoming&
__inS, const ::Ice::Current& __current)
{
    __checkMode(::Ice::Normal, __current.mode);
    ::IceInternal::BasicStream* __is = __inS.is();
    __is->startReadEncaps();
    ::Ice::Int num1;
    ::Ice::Int num2;
    __is->read(num1);
    __is->read(num2);
    __is->endReadEncaps();
    ::IceInternal::BasicStream* __os = __inS.os();
    ::Ice::Int __ret = add(num1, num2, __current);
    __os->write(__ret);
    return ::Ice::DispatchOK;
}
::Ice::DispatchStatusMCal::Cal::___sub(::IceInternal::Incoming&
__inS, const ::Ice::Current& __current)
{
    __checkMode(::Ice::Normal, __current.mode);
    ::IceInternal::BasicStream* __is = __inS.is();
    __is->startReadEncaps();
    ::Ice::Int num1;
    ::Ice::Int num2;
    __is->read(num1);
    __is->read(num2);
    __is->endReadEncaps();
    ::IceInternal::BasicStream* __os = __inS.os();
    ::Ice::Int __ret = sub(num1, num2, __current);
    __os->write(__ret);
    return ::Ice::DispatchOK;
}

static ::std::string __MCal__Cal_all[] =
{
    "add",
    "ice_id",
    "ice_ids",
    "ice_isA",
    "ice_ping",
    "sub"
};

::Ice::DispatchStatusMCal::Cal::__dispatch(::IceInternal::Incoming&
in, const ::Ice::Current& current)
{
    ::std::pair< ::std::string*, ::std::string*> r = ::std::equal_range(__MCal__Cal_all, __MCal__Cal_all + 6, current.operation);
    if(r.first == r.second)
    {
        throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
    }
    switch(r.first - __MCal__Cal_all)
    {
        case 0:
        {
            return ___add(in, current);
        }
        case 1:
        {
            return ___ice_id(in, current);
        }
        case 2:
        {
            return ___ice_ids(in, current);
        }
        case 3:
        {
            return ___ice_isA(in, current);
        }
        case 4:
        {
            return ___ice_ping(in, current);
        }
        case 5:
        {
            return ___sub(in, current);
        }
    }
    assert(false);
    throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
}

voidMCal::Cal::__write(::IceInternal::BasicStream*
__os) const
{
    __os->writeTypeId(ice_staticId());
    __os->startWriteSlice();
    __os->endWriteSlice();
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
    Object::__write(__os);
#else
    ::Ice::Object::__write(__os);
#endif
}

voidMCal::Cal::__read(::IceInternal::BasicStream*
__is, bool __rid)
{
    if(__rid)
    {
        ::std::string myId;
        __is->readTypeId(myId);
    }
__is->startReadSlice();
    __is->endReadSlice();
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
    Object::__read(__is, true);
#else
    ::Ice::Object::__read(__is, true);
#endif
}

// COMPILERFIX: Stream API is not supported with VC++ 6
#if !defined(_MSC_VER) || (_MSC_VER >= 1300)
voidMCal::Cal::__write(const ::Ice::OutputStreamPtr&)
const
{
    Ice::MarshalException ex(__FILE__, __LINE__);
    ex.reason = "type MCal::Cal was not generated with stream support";

throw
ex;

}

voidMCal::Cal::__read(const ::Ice::InputStreamPtr&,
bool)
{
    Ice::MarshalException ex(__FILE__, __LINE__);
    ex.reason = "type MCal::Cal was not generated with stream support";
    throw ex;
}
#endif

void MCal::__patch__CalPtr(void* __addr,
::Ice::ObjectPtr& v)
{
    ::MCal::CalPtr* p = static_cast< ::MCal::CalPtr*>(__addr);
    assert(p);
    *p = ::MCal::CalPtr::dynamicCast(v);
    if(v && !*p)
    {
        IceInternal::Ex::throwUOE(::MCal::Cal::ice_staticId(), v->ice_id());
    }
}

编译成功,如果有很多错误,可能是没有加入库文件iced.lib和iceutild.lib 如果成功,服务器端建立成功。

h、客户端程序main.cpp.

重新建立工程,Client,建立客户端CalculatorClient.cpp

将生成的Calculator.h 和Calculator.cpp加入Client工程中,然后建立CalculatorClient.cpp

#include <Ice/Ice.h>
#include <Ice/Application.h>
#include "Calculator.h"
#include<iostream>

using namespace std;
using namespace MCal;

//#define RC_List "/home/tester/Key_Checking/ATT_RC/RMT_B109P_EU_Set.txt"
//#define RC_Data "/home/tester/Key_Checking/ATT_RC/RMT_B109P_EU_Set.dat"

class MyApp : virtual public Ice::Application
{
public:
    virtual int run(int,char*[]);
};

int MyApp::run(int,char*[])
{
    Ice::ObjectPrx base = communicator()->stringToProxy("Cal:default -p 10000");
    CalPrx calculator = CalPrx::checkedCast(base);
    if(!calculator)
        throw "Invalid proxy!";
        cout<<calculator->add(1,2)<<endl;
       
        cout<<calculator->sub(56,12)<<endl;
   
   
    //Calc->Close();
    return 0;
}

int main(int argc,char* argv[])
{
    MyApp app;

return app.main(argc,argv);
}

至此,完成....!

附件,本demo示例源码见:http://download.csdn.net/detail/wqc19920906/9405766

ICE简介及C++程序例子(转)的更多相关文章

  1. Spark简介安装和简单例子

    Spark简介安装和简单例子 Spark简介 Spark是一种快速.通用.可扩展的大数据分析引擎,目前,Spark生态系统已经发展成为一个包含多个子项目的集合,其中包含SparkSQL.Spark S ...

  2. Ice简介+Qt代码示例

    1.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,它封装并 ...

  3. 微信小程序例子-保存图片到手机相册

    微信小程序例子-保存图片到手机相册 1.关键代码 1)WXML文件 2)JS文件 saveImgToPhotosAlbumTap: function(){ // 图片必须是 https 的 var I ...

  4. Peer模式的多线程程序例子

    Peer模式的多线程程序例子 程序的模型大概是这样的.有一个master(),用来分发任务.有N个多线程的slave用来处理任务. 主程序里可以这样调用: 可以看出,上面这段程序还是依赖于Proces ...

  5. 第15.35节 PyQt编程实战:结合QDial实现的QStackedWidget堆叠窗口程序例子

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.案例说明 本案例是老猿在学习QStackedWidget中的一个测试案例,该案例使用QStack ...

  6. The Internet Communications Engine (Ice) 跨平台异构通讯方案 第一弹-ICE简介

    .net中的通讯方案很多,从.net Remoting,MSMQ,Webservice,WSE,WCF等等,他们都有一个特点,易用,但是都不能跨语种异构,如果你服务端要用java开发,客户端用C#开发 ...

  7. Ruby简介,附带示例程序

    Ruby语言是日本人松本行弘于1993年器开始着手研发,经历2年时间,发布了Ruby语言的第一个版本:0.95版.     Ruby是一种非常简介的解释性语言,一种纯粹的面向对象编程语言,甚至比Jav ...

  8. IDEA下调试和运行Hadoop程序例子

    准备 配置好JDK和Hadoop环境, 在IDEA中建立maven项目,建立后的目录结构为: 修改pom..xml引入相关支持: <?xml version="1.0" en ...

  9. Spring Cloud简介/版本选择/ZooKeeper例子搭建简单说明

    一.什么是Spring Cloud 官方的说法就是Spring Cloud 给开发者提供一套按照一定套路快速开发分布式系统的工具. 具体点就是Spring Boot实现的微服务架构开发工具.它为微服务 ...

随机推荐

  1. SGU 110. Dungeon 计算几何 难度:3

    110. Dungeon time limit per test: 0.25 sec. memory limit per test: 4096 KB The mission of space expl ...

  2. 关于rowid的函数

    1. select dbms_rowid.rowid_object(rowid) object_id, dbms_rowid.rowid_relative_fno(rowid) file_id, db ...

  3. 如何以编程方式打印到在 MFC 中的非默认打印机

    http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105790245b09c0252bd7a74a2485d315d2390f0750 ...

  4. python 安装 scapy windows 10 64bit

    简介: 前段时间装的pypcap做嗅探.打包受阻.因为我都是在windows做的.也要打包到exe给别人用. 所以尝试了一下scapy,也可以嗅探,貌似功能更强大.先用sniff吧. 这个也不是在ve ...

  5. selenium安装后,需要安装浏览器驱动

    google的驱动:chromedriver.exe 驱动版本与chrome版本对应的目录: http://npm.taobao.org/mirrors/chromedriver/2.32/notes ...

  6. iOS-----使用CFNetwork实现TCP协议的通信

    使用CFNetwork实现TCP协议的通信 TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个通信接口,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以 ...

  7. 【error】select timeout问题

    使用摄像头的过程中出现这个问题,说明是找不到摄像头了, 有可能是摄像头驱动问题,也有可能是摄像头接口处接触不良等原因造成的. re 1.select-timeout-opencv; End

  8. C#单例的多种写法

    单例的细分写法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 最吊大的 一种--C#这样的高级语言特有 ...

  9. 2243: [SDOI2011]染色(LCT)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 10909  Solved: 4216[Submit][Statu ...

  10. CTF-练习平台-Misc之 隐写2

    二.隐写2 下载文件后解压,发现是一个png图片,依照老套路查看属性,没有发现 用WinHex打开,在图片文件中,修改图片宽度,将箭头处的A改为F,保存后打开图片 发现flag(对于png的文件格式详 ...