status=1;
}
if(ic)
ic->destroy();
returnstatus;
}
如果出现任何错误,客户会打印一条出错消息。
例如,如果我们没有先启动服务器就运行客户,我们会得到:
Network.cpp:
471:
Ice:
:
ConnectFailedException:
connectfailed:
Connectionrefused
(由于windows下的命令行窗口在出错后会一闪就消失,不过我们可以在client.cpp的main函数的returnstatus;之前加上system("PAUSE");然后再在VS中把client设置为启动项目,重新编译,运行。
OK,可以看到结果了。
)
Slice语言
首先,请大家读ICE中文手册中的Slice语言一章。
这一部分除了model(模块),在ICE1.3中文手册中都有描述
图 2.1. ice网络编程示意图(服务器端和客户端采用同种编程语言C++)
图 2.2. ice网络编程示意图(服务器端和客户端采用不同编程语言)
基础知识
含有Slice定义的文件必须以.ice扩展名结尾,例如,Clock.ice就是一个有效的文件名。
编译器拒绝接受其他扩展名。
Slice支持#ifndef、#define、#endif,以及#include预处理指令。
它们的使用方式有严格的限制:
你只能把#ifndef、#define,以及#endif指令用于创建双包括(double-include)块。
例如:
#ifndef_CLOCK_ICE
#define_CLOCK_ICE
//#include文件here...
//定义here...
#endif_CLOCK_ICE
我们强烈建议你在所有的Slice定义中使用双包括(double-include)块(所上),防止多次包括同一文件。
#include指令只能出现在Slice源文件的开头,也就是说,它们必须出现在其他所有Slice定义的前面。
此外,在使用#include指令时,只允许使用<>语法来指定文件名,不能使用""。
例如:
#include//OK
#include"File2.ice"//不支持!
你不能把这些预处理指令用于其他目的,也不能使用其他的C++预处理指令(比如用/字符来连接行、token粘贴,以及宏展开,等等)。
在Slice定义里,既可以使用C的、也可以使用C++的注释风格:
Slice关键字必须小写。
例如,class和dictionary都是关键字,必须按照所示方式拼写。
这个规则有两个例外:
Object和LocalObject也是关键字,必须按照所示方式让首字母大写。
标识符以一个字母起头,后面可以跟任意数目的字母或数字。
Slice标识符被限制在ASCII字符范围内,不能包含非英语字母,与C++标识符不同,Slice标识符不能有下划线。
这种限制初看上去显得很苛刻,但却是必要的:
保留下划线,各种语言映射就获得了一个名字空间,不会与合法的Slice标识符发生冲突。
于是,这个名字空间可用于存放从Slice标识符派生的原生语言标识符,而不用担心其他合法的Slice标识符会碰巧与之相同,从而发生冲突。
标识符(变量名等等)是大小写不敏感的,但大小写的拼写方式必须保持一致(看了后面的话,再理解一下)。
例如,在一个作用域内,TimeOfDay和TIMEOFDAY被认为是同一个标识符。
但是,Slice要求你保持大小写的一致性。
在你引入了一个标识符之后,你必须始终一致地拼写它的大写和小写字母;否则,编译器就会将其视为非法而加以拒绝。
这条规则之所以存在,是要让Slice既能映射到忽略标识符大小写的语言,又能映射到把大小写不同的标识符当作不同标识符的语言。
(可以这样理解,变量名区分大小写,并且不可以是相同的单词)
是关键字的标识符:
你可以定义在一种或多种实现语言中是关键字的Slice标识符。
例如,switch是完全合法的Slice标识符,但也是C++和Java的关键字。
语言映射定义了一些规则来处理这样的标识符。
要解决这个问题,通常要用一个前缀来使映射后的标识符不再是关键字。
例如,Slice标识符switch被映射到C++的_cpp_switch,以及Java的_switch。
对关键字进行处理的规则可能会产生难以阅读的源码。
像native、throw,或export这样的标识符会与C++或Java(或两者)的关键字发生冲突。
为了让你和别人生活得更轻松一点,你应该避免使用是实现语言的关键字的Slice标识符。
要记住,以后Ice可能会增加除C++和Java以外的语言映射。
尽管期望你总结出所有流行的编程语言的所有关键字并不合理,你至少应该尽量避免使用常用的关键字。
使用像self、import,以及while这样的标识符肯定不是好主意。
转义的标识符:
在关键字的前面加上一个反斜线,你可以把Slice关键字用作标识符,例如:
structdictionary{//错误!
//...
};
struct/dictionary{//OK
//...
};
反斜线会改变关键字通常的含义;在前面的例子中,/dictionary被当作标识符dictionary。
转义机制之所以存在,是要让我们在以后能够在Slice中增加关键字,同时尽量减少对已有规范的影响:
如果某个已经存在的规范碰巧使用了新引入的关键字,你只需在新关键字前加上反斜线,就能够修正该规范。
注意,从风格上说,你应该避免用Slice关键字做标识符(即使反斜线转义允许你这么做)。
保留的标识符:
Slice为Ice实现保留了标识符Ice及以Ice(任何大小写方式)起头的所有标识符。
例如,如果你试图定义一个名为Icecream的类型,Slice编译器会发出错误警告3。
以下面任何一种后缀结尾的Slice标识符也是保留的:
Helper、Holder、Prx,以及Ptr。
Java和C++语言映射使用了这些后缀,保留它们是为了防止在生成的代码中发生冲突。
(注:
ICE1.3的中文手册上没有“模块”这一部分)模块来组织一组相关的语句是为了解决名字冲突。
模块可以包含所有合法的Slice语句和子模块。
你可以用一些不常用的词来给最外层的模块命名,比如公司名、产品名等等。
moduleZeroC{
moduleClient{
//Definitionshere...
};
moduleServer{
//Definitionshere...
};
};
Slice要求所有的定义都是模块的一部分,比如,下面的语句就是非法的。
interfaceI{//错误:
全局空间中只可以有模块
//...
};
多个文件可以共享同一个模块,比如:
moduleZeroC{
//Definitionshere...