客户端使用java,服务端使用c++的corba编程环境搭建

Posted zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户端使用java,服务端使用c++的corba编程环境搭建相关的知识,希望对你有一定的参考价值。

我们先用c++实现服务端和客户端,然后再用java编写客户端。

 

1. 首先安装omniORB,omniORB提供 omniidl命令,以及一些头文件和库。

omniORB一般是需要你自己进行编译。

 

2. 编写idl文件,本实验中文件名为 echo.idl

1 interface Echo { string echoString(in string mesg); };
echo.idl

 

3. 使用omniidl -bcxx echo.idl 生成 echo.hh 和 echoSK.cc

 

4. 编写用c++实现的服务端和客户端,本实验中是 server.cpp client.cpp

  1 // eg3_impl.cc - This is the source code of example 3 used in Chapter 2
  2 //               "The Basics" of the omniORB user guide.
  3 //
  4 //               This is the object implementation.
  5 //
  6 // Usage: eg3_impl
  7 //
  8 //        On startup, the object reference is registered with the
  9 //        COS naming service. The client uses the naming service to
 10 //        locate this object.
 11 //
 12 //        The name which the object is bound to is as follows:
 13 //              root  [context]
 14 //               |
 15 //              test  [context] kind [my_context]
 16 //               |
 17 //              Echo  [object]  kind [Object]
 18 //
 19 
 20 #include "echo.hh"
 21 
 22 #ifdef HAVE_STD
 23 #  include <iostream>
 24    using namespace std;
 25 #else
 26 #  include <iostream.h>
 27 #endif
 28 
 29 static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr);
 30 
 31 
 32 class Echo_i : public POA_Echo
 33 {
 34 public:
 35   inline Echo_i() {}
 36   virtual ~Echo_i() {}
 37   virtual char* echoString(const char* mesg);
 38 };
 39 
 40 
 41 char* Echo_i::echoString(const char* mesg)
 42 {
 43   return CORBA::string_dup(mesg);
 44 }
 45 
 46 //////////////////////////////////////////////////////////////////////
 47 
 48 int
 49 main(int argc, char **argv)
 50 {
 51   try {
 52     CORBA::ORB_var          orb = CORBA::ORB_init(argc, argv);
 53     CORBA::Object_var       obj = orb->resolve_initial_references("RootPOA");
 54     PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
 55 
 56     PortableServer::Servant_var<Echo_i> myecho = new Echo_i();
 57 
 58     PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);
 59 
 60     // Obtain a reference to the object, and register it in
 61     // the naming service.
 62     obj = myecho->_this();
 63 
 64     CORBA::String_var sior(orb->object_to_string(obj));
 65     cout << sior << endl;
 66 
 67     if (!bindObjectToName(orb, obj))
 68       return 1;
 69 
 70     PortableServer::POAManager_var pman = poa->the_POAManager();
 71     pman->activate();
 72 
 73     orb->run();
 74   }
 75   catch (CORBA::SystemException& ex) {
 76     cerr << "Caught CORBA::" << ex._name() << endl;
 77   }
 78   catch (CORBA::Exception& ex) {
 79     cerr << "Caught CORBA::Exception: " << ex._name() << endl;
 80   }
 81   return 0;
 82 }
 83 
 84 //////////////////////////////////////////////////////////////////////
 85 
 86 static CORBA::Boolean
 87 bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
 88 {
 89   CosNaming::NamingContext_var rootContext;
 90 
 91   try {
 92     // Obtain a reference to the root context of the Name service:
 93     CORBA::Object_var obj = orb->resolve_initial_references("NameService");
 94 
 95     // Narrow the reference returned.
 96     rootContext = CosNaming::NamingContext::_narrow(obj);
 97     if (CORBA::is_nil(rootContext)) {
 98       cerr << "Failed to narrow the root naming context." << endl;
 99       return 0;
100     }
101   }
102   catch (CORBA::NO_RESOURCES&) {
103     cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
104      << "with the location" << endl
105      << "of the naming service." << endl;
106     return 0;
107   }
108   catch (CORBA::ORB::InvalidName&) {
109     // This should not happen!
110     cerr << "Service required is invalid [does not exist]." << endl;
111     return 0;
112   }
113 
114   try {
115     // Bind a context called "test" to the root context:
116 
117     CosNaming::Name contextName;
118     contextName.length(1);
119     contextName[0].id   = (const char*) "test";       // string copied
120     contextName[0].kind = (const char*) "my_context"; // string copied
121     // Note on kind: The kind field is used to indicate the type
122     // of the object. This is to avoid conventions such as that used
123     // by files (name.type -- e.g. test.ps = postscript etc.)
124 
125     CosNaming::NamingContext_var testContext;
126     try {
127       // Bind the context to root.
128       testContext = rootContext->bind_new_context(contextName);
129     }
130     catch(CosNaming::NamingContext::AlreadyBound& ex) {
131       // If the context already exists, this exception will be raised.
132       // In this case, just resolve the name and assign testContext
133       // to the object returned:
134       CORBA::Object_var obj = rootContext->resolve(contextName);
135       testContext = CosNaming::NamingContext::_narrow(obj);
136       if (CORBA::is_nil(testContext)) {
137         cerr << "Failed to narrow naming context." << endl;
138         return 0;
139       }
140     }
141 
142     // Bind objref with name Echo to the testContext:
143     CosNaming::Name objectName;
144     objectName.length(1);
145     objectName[0].id   = (const char*) "Echo";   // string copied
146     objectName[0].kind = (const char*) "Object"; // string copied
147 
148     try {
149       testContext->bind(objectName, objref);
150     }
151     catch(CosNaming::NamingContext::AlreadyBound& ex) {
152       testContext->rebind(objectName, objref);
153     }
154     // Note: Using rebind() will overwrite any Object previously bound
155     //       to /test/Echo with obj.
156     //       Alternatively, bind() can be used, which will raise a
157     //       CosNaming::NamingContext::AlreadyBound exception if the name
158     //       supplied is already bound to an object.
159   }
160   catch (CORBA::TRANSIENT& ex) {
161     cerr << "Caught system exception TRANSIENT -- unable to contact the "
162          << "naming service." << endl
163      << "Make sure the naming server is running and that omniORB is "
164      << "configured correctly." << endl;
165 
166     return 0;
167   }
168   catch (CORBA::SystemException& ex) {
169     cerr << "Caught a CORBA::" << ex._name()
170      << " while using the naming service." << endl;
171     return 0;
172   }
173   return 1;
174 }
server.cpp
  1 // eg3_clt.cc - This is the source code of example 3 used in Chapter 2
  2 //              "The Basics" of the omniORB user guide.
  3 //
  4 //              This is the client. It uses the COSS naming service
  5 //              to obtain the object reference.
  6 //
  7 // Usage: eg3_clt
  8 //
  9 //
 10 //        On startup, the client lookup the object reference from the
 11 //        COS naming service.
 12 //
 13 //        The name which the object is bound to is as follows:
 14 //              root  [context]
 15 //               |
 16 //              text  [context] kind [my_context]
 17 //               |
 18 //              Echo  [object]  kind [Object]
 19 //
 20 
 21 #include "echo.hh"
 22 
 23 #ifdef HAVE_STD
 24 #  include <iostream>
 25    using namespace std;
 26 #else
 27 #  include <iostream.h>
 28 #endif
 29 
 30 static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb);
 31 
 32 static void hello(Echo_ptr e)
 33 {
 34   if (CORBA::is_nil(e)) {
 35     cerr << "hello: The object reference is nil!\\n" << endl;
 36     return;
 37   }
 38 
 39   CORBA::String_var src = (const char*) "Hello!";
 40 
 41   CORBA::String_var dest = e->echoString(src);
 42 
 43   cerr << "I said, \\"" << (char*)src << "\\"." << endl
 44        << "The Echo object replied, \\"" << (char*)dest <<"\\"." << endl;
 45 }
 46 
 47 //////////////////////////////////////////////////////////////////////
 48 
 49 int
 50 main (int argc, char **argv) 
 51 {
 52   try {
 53     CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
 54 
 55     CORBA::Object_var obj = getObjectReference(orb);
 56 
 57     Echo_var echoref = Echo::_narrow(obj);
 58 
 59     for (CORBA::ULong count=0; count < 10; count++)
 60       hello(echoref);
 61 
 62     orb->destroy();
 63   }
 64   catch (CORBA::TRANSIENT&) {
 65     cerr << "Caught system exception TRANSIENT -- unable to contact the "
 66          << "server." << endl;
 67   }
 68   catch (CORBA::SystemException& ex) {
 69     cerr << "Caught a CORBA::" << ex._name() << endl;
 70   }
 71   catch (CORBA::Exception& ex) {
 72     cerr << "Caught CORBA::Exception: " << ex._name() << endl;
 73   }
 74   return 0;
 75 }
 76 
 77 //////////////////////////////////////////////////////////////////////
 78 
 79 static CORBA::Object_ptr
 80 getObjectReference(CORBA::ORB_ptr orb)
 81 {
 82   CosNaming::NamingContext_var rootContext;
 83   
 84   try {
 85     // Obtain a reference to the root context of the Name service:
 86     CORBA::Object_var obj;
 87     obj = orb->resolve_initial_references("NameService");
 88 
 89     // Narrow the reference returned.
 90     rootContext = CosNaming::NamingContext::_narrow(obj);
 91 
 92     if (CORBA::is_nil(rootContext)) {
 93       cerr << "Failed to narrow the root naming context." << endl;
 94       return CORBA::Object::_nil();
 95     }
 96   }
 97   catch (CORBA::NO_RESOURCES&) {
 98     cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
 99      << "with the location" << endl
100      << "of the naming service." << endl;
101     return CORBA::Object::_nil();
102   }
103   catch (CORBA::ORB::InvalidName& ex) {
104     // This should not happen!
105     cerr << "Service required is invalid [does not exist]." << endl;
106     return CORBA::Object::_nil();
107   }
108 
109   // Create a name object, containing the name test/context:
110   CosNaming::Name name;
111   name.length(2);
112 
113   name[0].id   = (const char*) "test";       // string copied
114   name[0].kind = (const char*) "my_context"; // string copied
115   name[1].id   = (const char*) "Echo";
116   name[1].kind = (const char*) "Object";
117   // Note on kind: The kind field is used to indicate the type
118   // of the object. This is to avoid conventions such as that used
119   // by files (name.type -- e.g. test.ps = postscript etc.)
120 
121   try {
122     // Resolve the name to an object reference.
123     return rootContext->resolve(name);
124   }
125   catch (CosNaming::NamingContext::NotFound& ex) {
126     // This exception is thrown if any of the components of the
127     // path [contexts or the object] aren\'t found:
128     cerr << "Context not found." << endl;
129   }
130   catch (CORBA::TRANSIENT& ex) {
131     cerr << "Caught system exception TRANSIENT -- unable to contact the "
132          << "naming service." << endl
133      << "Make sure the naming server is running and that omniORB is "
134      << "configured correctly." << endl;
135   }
136   catch (CORBA::SystemException& ex) {
137     cerr << "Caught a CORBA::" << ex._name()
138      << " while using the naming service." << endl;
139   }
140   return CORBA::Object::_nil();
141 }
client.cpp

 

5. 编写makefile,用于生成c++的客户端和服务端

 1 CXX=g++
 2 FLAGS=-Wall
 3 
 4 all:server client
 5 
 6 server:server.cpp echoSK.cc echo.hh
 7     $(CXX) $(FLAGS) -o $@ server.cpp echoSK.cc -lomnithread -lomniORB4
 8     
 9 client:client.cpp echoSK.cc echo.hh
10     $(CXX) $(FLAGS) -o $@ client.cpp echoSK.cc -lomnithread -lomniORB4
11     
12 clean:
13     rm server client
14     
15     
makefile

 

6. 执行make命令,生成 server 和client 的二进制文件

 

7. 启动 tnameserv

sudo tnameserv

该命令会同时告诉我们端口号,这里是900

 

8. 启动服务端

./server -ORBInitRef NameService=corbaloc::localhost:900/NameService

 

9. 启动客户端

./client -ORBInitRef NameService=corbaloc::localhost:900/NameService

 

10. 现在为止,我们已经用 c++ 实现了服务端和客户端,接下来我们用java实现客户端,服务端依然使用之前 make 生成的。

 

11. 现在用idlj 生成一些必要的 java 文件

idlj echo.idl

 

12. 编写java客户端,本实验中是 javaclient.java

 1 //import HelloApp.*;
 2 import org.omg.CosNaming.*;
 3 import org.omg.CosNaming.NamingContextPackage.*;
 4 import org.omg.CORBA.*;
 5 
 6 public class javaclient
 7 {
 8   static Echo echoImpl;
 9 
10   public static void main(String args[])
11     {
12       try{
13         // create and initialize the ORB
14     ORB orb = ORB.init(args, null);
15 
16         // get the root naming context
17         org.omg.CORBA.Object objRef = 
18         orb.resolve_initial_references("NameService");
19         // Use NamingContextExt instead of NamingContext. This is 
20         // part of the Interoperable naming Service.  
21         NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
22  
23         // resolve the Object Reference in Naming
24         //String name = "Hello";
25         NameComponent name0=new NameComponent("test","my_context");
26         NameComponent name1=new NameComponent("Echo","Object");
27         echoImpl = EchoHelper.narrow(ncRef.resolve(new NameComponent[]{name0,name1}));
28 
29         System.out.println("Obtained a handle on server object: " + echoImpl);
30         System.out.println(echoImpl.echoString("Hello"));
31         //echoImpl.shutdown();
32 
33     } catch (Exception e) {
34           System.out.println("ERROR : " + e) ;
35       e.printStackTrace(System.out);
36       }
37     }
如何从服务器获取我的 Corba 客户端的 IP 地址

MICO Corba 的直接替代品?

CORBA omniorb C++ 多个仆人

使用带有 SSL 的 JacORB (Java/CORBA) 的客户端策略错误

Corba 客户端 - Python 和 Corba 服务器 - Java

使用 CORBA - org.omg.CORBA.BAD_PARAM 连接客户端(在 VirtualBox 上)和服务器(在 localhost 上):