• 客户端使用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!
    " << 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     }
    38 
    39 }
    javaclient.java

    13. 编译java 客户端

    javac *.java

    14. 执行java客户端

    java javaclient -ORBInitRef NameService=corbaloc::localhost:900/NameService

    15. 附带给出一个脚本,用于删除那些由程序生成的文件,可以用来清理项目

     1 #!/bin/bash
     2 
     3 rm client
     4 rm server
     5 rm *.class
     6 rm echo.hh
     7 rm echoSK.cc
     8 rm _EchoStub.java
     9 rm EchoHelper.java
    10 rm EchoHolder.java
    11 rm EchoOperations.java
    rmunneededfile.sh

    16. 结束

    Trouble shooting:

    1. 编译出来c++的server,在运行时出现没有找到.so的问题,于是使用ldd命令找到运行server时缺少的库,实际的.so所在的目录是/usr/local/lib,尝试将该目录添加到PATH环境变量中,发现没有效果(大概寻找.so时搜索的路径不是PATH环境变量),于是在/usr/lib下建了所缺少的.so的符号链接,问题解决。

    2. 在ubuntu中,编译omniORB会出现无法找到python头文件的问题,原因是python的头文件存在于单独的包中,名为 libpython2.7-dev。

  • 相关阅读:
    Linux 内核中的 Device Mapper 机制
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Docker容器 暴露多个端口
    修改docker容器的端口映射
    Ubuntu Docker安装
    Docker容器技术的PaaS云平台架构设计***
    scala 学习笔记三 闭包
    scala 学习笔记二 方法与函数
    scala 学习笔记一 列表List
    Python3 写Windows Service服务程序
  • 原文地址:https://www.cnblogs.com/vanwoos/p/5573383.html
Copyright © 2020-2023  润新知