客户端与服务器双方的语言使用:client(C++), server(Java)。
首先下载好ice安装包,这里使用Ice-3.3.1-VC60版本。安装后配置环境变量以及VC6.0中目录里相关设置(execute, lib, include)。
接下来编写slice文件,后缀名为.ice
//Printer.ice module Demo { interface Printer { void printString(string s); }; };
打开命令行,转到Printer.ice所在目录,输入slice2cpp Printer.ice命令进行编译。提示如下错误:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
查找错误,还以为是变量没配好,最后发现文件路径里不能有中文。放到别的目录下,编译成功,生成Printer.c文件和Printer.cpp文件。
编写客户端文件client.cpp
//client.cpp #include <Ice/Ice.h> #include "Printer.h" using namespace Demo; int main(int argc, char * argv[]) { // Initialize Ice Ice::CommunicatorPtr c = Ice::initialize(argc, argv); // Get proxy for the object with the identity “SimplePrinter” // The server is running on host 127.0.0.1, port 10000 Ice::ObjectPrx base = c->stringToProxy("SimplePrinter:default -p 10000"); // Down-cast base proxy to Printer proxy (like dynamic_cast<>) PrinterPrx printer = PrinterPrx::checkedCast(base); // Send “Hello World” to the server printer->printString("Hello World!"); // Cleanup c->destroy(); return 0; }
建立一个windows console工程,把client.cpp, Printer.cpp, Printer.h加进去编译,会报一系列错误。如下:
1. fatal error C1189: #error : "Only multi-threaded DLL libraries can be used with Ice!"
解决方法:工程 -> 设置 -> C/C++ -> Code generation -> 运行库设为Multithreaded DLL。
2. 一大堆错误
解决方法:工程 -> 设置 -> 链接 -> 加入这两个库iced.lib iceutild.lib。
3. 一定要把ice文件中的module,这里作命名空间引入using namespace Demo。
最后编译成功。
编写服务器端文件Server.java
这里需要用命令行的slice2java命令编译先前的Printer.ice文件。但在Ice VC60安装目录的bin中找不到这个命令。又安装了个Ice VC90版的,里面有此命令。而且lib里有需要的Ice.jar文件。
编译:slice2java Printer.ice。生成了Demo目录。里面文件如下:
Printer.java
PrinterHolder.java
PrinterPrx.java
PrinterPrxHelper.java
PrinterPrxHolder.java
_PrinterDel.java
_PrinterDelD.java
_PrinterDelM.java
_PrinterDisp.java
_PrinterOperations.java
_PrinterOperationsNC.java
首先写一个继承类Printer1.java,这个类重写printString方法实现主要的功能,其他在Server.java里面都是一些固定的写法。主要内容在这里。
// Printer1.java // Implementation of the Printer interface, // by extending the generated printer skeleton public class Printer1 extends Demo._PrinterDisp { // Implementation of printString simply // prints the message on standard output public void printString(String s, Ice.Current current) { System.out.println(s); //主要功能 } }
再写Server.java
// Server.java public class Server { public static void main(String[] args) { // Initialize Ice Ice.Communicator c = Ice.Util.initialize(args); // Create an object adapter, which listens on port 10000, using TCP/IP Ice.ObjectAdapter adapter = c.createObjectAdapterWithEndpoints( "SimplePrinterAdapter", "tcp -p 10000"); // Create servant (implementation) object Ice.Object object = new Printer1(); // Add servant to the object adapter’s active servant map adapter.add(object, Ice.Util.stringToIdentity("SimplePrinter")); // Activate the object adapter adapter.activate(); // Just wait until we’re finished c.waitForShutdown(); } }
至此,程序基本完成。运行Server.java,服务器开始在10000端口监听。运行client.exe,服务器端即收到了客户端发来的久违的Hello World。
最后因为项目要用到C#,再用C#写个server,与Java类似。引用Ice.dll后,在程序里using Ice。就可以编写程序了。
当然,先要用slice2cs Printer.ice生成Printer.cs类文件。
Printer1.cs
using System; public class Printer1 : Demo.PrinterDisp_ { public override void printString(String s, Ice.Current current) { Console.WriteLine(s); } }
Server.cs
using System; using Ice; public class Server { static void Main(string[] args) { int status = 0; Ice.Communicator ic = null; try { ic = Ice.Util.initialize(ref args); Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints( "SimplePrinterAdapter", "default -p 10000"); Ice.Object obj = new Printer1(); adapter.add( obj, Ice.Util.stringToIdentity("SimplePrinter")); adapter.activate(); ic.waitForShutdown(); } catch (System.Exception e) { Console.Error.WriteLine(e); status = 1; } finally { if (ic != null) ic.destroy(); } Environment.Exit(status); } }
结束。