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

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

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

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

 interface Echo { string echoString(in string mesg); };

echo.idl

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

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

 // eg3_impl.cc - This is the source code of example 3 used in Chapter 2
// "The Basics" of the omniORB user guide.
//
// This is the object implementation.
//
// Usage: eg3_impl
//
// On startup, the object reference is registered with the
// COS naming service. The client uses the naming service to
// locate this object.
//
// The name which the object is bound to is as follows:
// root [context]
// |
// test [context] kind [my_context]
// |
// Echo [object] kind [Object]
// #include "echo.hh" #ifdef HAVE_STD
# include <iostream>
using namespace std;
#else
# include <iostream.h>
#endif static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr); class Echo_i : public POA_Echo
{
public:
inline Echo_i() {}
virtual ~Echo_i() {}
virtual char* echoString(const char* mesg);
}; char* Echo_i::echoString(const char* mesg)
{
return CORBA::string_dup(mesg);
} ////////////////////////////////////////////////////////////////////// int
main(int argc, char **argv)
{
try {
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj); PortableServer::Servant_var<Echo_i> myecho = new Echo_i(); PortableServer::ObjectId_var myechoid = poa->activate_object(myecho); // Obtain a reference to the object, and register it in
// the naming service.
obj = myecho->_this(); CORBA::String_var sior(orb->object_to_string(obj));
cout << sior << endl; if (!bindObjectToName(orb, obj))
return ; PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate(); orb->run();
}
catch (CORBA::SystemException& ex) {
cerr << "Caught CORBA::" << ex._name() << endl;
}
catch (CORBA::Exception& ex) {
cerr << "Caught CORBA::Exception: " << ex._name() << endl;
}
return ;
} ////////////////////////////////////////////////////////////////////// static CORBA::Boolean
bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
{
CosNaming::NamingContext_var rootContext; try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj = orb->resolve_initial_references("NameService"); // Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj);
if (CORBA::is_nil(rootContext)) {
cerr << "Failed to narrow the root naming context." << endl;
return ;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
<< "with the location" << endl
<< "of the naming service." << endl;
return ;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "Service required is invalid [does not exist]." << endl;
return ;
} try {
// Bind a context called "test" to the root context: CosNaming::Name contextName;
contextName.length();
contextName[].id = (const char*) "test"; // string copied
contextName[].kind = (const char*) "my_context"; // string copied
// Note on kind: The kind field is used to indicate the type
// of the object. This is to avoid conventions such as that used
// by files (name.type -- e.g. test.ps = postscript etc.) CosNaming::NamingContext_var testContext;
try {
// Bind the context to root.
testContext = rootContext->bind_new_context(contextName);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var obj = rootContext->resolve(contextName);
testContext = CosNaming::NamingContext::_narrow(obj);
if (CORBA::is_nil(testContext)) {
cerr << "Failed to narrow naming context." << endl;
return ;
}
} // Bind objref with name Echo to the testContext:
CosNaming::Name objectName;
objectName.length();
objectName[].id = (const char*) "Echo"; // string copied
objectName[].kind = (const char*) "Object"; // string copied try {
testContext->bind(objectName, objref);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
testContext->rebind(objectName, objref);
}
// Note: Using rebind() will overwrite any Object previously bound
// to /test/Echo with obj.
// Alternatively, bind() can be used, which will raise a
// CosNaming::NamingContext::AlreadyBound exception if the name
// supplied is already bound to an object.
}
catch (CORBA::TRANSIENT& ex) {
cerr << "Caught system exception TRANSIENT -- unable to contact the "
<< "naming service." << endl
<< "Make sure the naming server is running and that omniORB is "
<< "configured correctly." << endl; return ;
}
catch (CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
return ;
}
return ;
}

server.cpp

 // eg3_clt.cc - This is the source code of example 3 used in Chapter 2
// "The Basics" of the omniORB user guide.
//
// This is the client. It uses the COSS naming service
// to obtain the object reference.
//
// Usage: eg3_clt
//
//
// On startup, the client lookup the object reference from the
// COS naming service.
//
// The name which the object is bound to is as follows:
// root [context]
// |
// text [context] kind [my_context]
// |
// Echo [object] kind [Object]
// #include "echo.hh" #ifdef HAVE_STD
# include <iostream>
using namespace std;
#else
# include <iostream.h>
#endif static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb); static void hello(Echo_ptr e)
{
if (CORBA::is_nil(e)) {
cerr << "hello: The object reference is nil!\n" << endl;
return;
} CORBA::String_var src = (const char*) "Hello!"; CORBA::String_var dest = e->echoString(src); cerr << "I said, \"" << (char*)src << "\"." << endl
<< "The Echo object replied, \"" << (char*)dest <<"\"." << endl;
} ////////////////////////////////////////////////////////////////////// int
main (int argc, char **argv)
{
try {
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); CORBA::Object_var obj = getObjectReference(orb); Echo_var echoref = Echo::_narrow(obj); for (CORBA::ULong count=; count < ; count++)
hello(echoref); orb->destroy();
}
catch (CORBA::TRANSIENT&) {
cerr << "Caught system exception TRANSIENT -- unable to contact the "
<< "server." << endl;
}
catch (CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name() << endl;
}
catch (CORBA::Exception& ex) {
cerr << "Caught CORBA::Exception: " << ex._name() << endl;
}
return ;
} ////////////////////////////////////////////////////////////////////// static CORBA::Object_ptr
getObjectReference(CORBA::ORB_ptr orb)
{
CosNaming::NamingContext_var rootContext; try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = orb->resolve_initial_references("NameService"); // Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj); if (CORBA::is_nil(rootContext)) {
cerr << "Failed to narrow the root naming context." << endl;
return CORBA::Object::_nil();
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
<< "with the location" << endl
<< "of the naming service." << endl;
return CORBA::Object::_nil();
}
catch (CORBA::ORB::InvalidName& ex) {
// This should not happen!
cerr << "Service required is invalid [does not exist]." << endl;
return CORBA::Object::_nil();
} // Create a name object, containing the name test/context:
CosNaming::Name name;
name.length(); name[].id = (const char*) "test"; // string copied
name[].kind = (const char*) "my_context"; // string copied
name[].id = (const char*) "Echo";
name[].kind = (const char*) "Object";
// Note on kind: The kind field is used to indicate the type
// of the object. This is to avoid conventions such as that used
// by files (name.type -- e.g. test.ps = postscript etc.) try {
// Resolve the name to an object reference.
return rootContext->resolve(name);
}
catch (CosNaming::NamingContext::NotFound& ex) {
// This exception is thrown if any of the components of the
// path [contexts or the object] aren't found:
cerr << "Context not found." << endl;
}
catch (CORBA::TRANSIENT& ex) {
cerr << "Caught system exception TRANSIENT -- unable to contact the "
<< "naming service." << endl
<< "Make sure the naming server is running and that omniORB is "
<< "configured correctly." << endl;
}
catch (CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
}
return CORBA::Object::_nil();
}

client.cpp

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

 CXX=g++
FLAGS=-Wall all:server client server:server.cpp echoSK.cc echo.hh
$(CXX) $(FLAGS) -o $@ server.cpp echoSK.cc -lomnithread -lomniORB4 client:client.cpp echoSK.cc echo.hh
$(CXX) $(FLAGS) -o $@ client.cpp echoSK.cc -lomnithread -lomniORB4 clean:
rm server client

makefile

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

7. 启动 tnameserv

sudo tnameserv

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

8. 启动服务端

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

9. 启动客户端

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

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

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

idlj echo.idl

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

 //import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*; public class javaclient
{
static Echo echoImpl; public static void main(String args[])
{
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null); // get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
// Use NamingContextExt instead of NamingContext. This is
// part of the Interoperable naming Service.
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // resolve the Object Reference in Naming
//String name = "Hello";
NameComponent name0=new NameComponent("test","my_context");
NameComponent name1=new NameComponent("Echo","Object");
echoImpl = EchoHelper.narrow(ncRef.resolve(new NameComponent[]{name0,name1})); System.out.println("Obtained a handle on server object: " + echoImpl);
System.out.println(echoImpl.echoString("Hello"));
//echoImpl.shutdown(); } catch (Exception e) {
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
}
} }

javaclient.java

13. 编译java 客户端

javac *.java

14. 执行java客户端

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

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

 #!/bin/bash

 rm client
rm server
rm *.class
rm echo.hh
rm echoSK.cc
rm _EchoStub.java
rm EchoHelper.java
rm EchoHolder.java
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。

客户端使用java,服务端使用c++的corba编程环境搭建的更多相关文章

  1. C#使用Thrift简介,C#客户端和Java服务端相互交互

    C#使用Thrift简介,C#客户端和Java服务端相互交互 本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实 ...

  2. RPC学习--C#使用Thrift简介,C#客户端和Java服务端相互交互

    本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实现Client和Server C#服务端,Java客户端 其中 ...

  3. Socket通讯-C#客户端与Java服务端通讯(发送消息和文件)

    设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能. Java服务端设计 packag ...

  4. Unity3D客户端和Java服务端使用Protobuf

    转自:http://blog.csdn.net/kakashi8841/article/details/17334493 前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖 ...

  5. C++客户端访问Java服务端发布的SOAP模式的WebService接口

    gSOAP是一个绑定SOAP/XML到C/C++语言的工具,使用它可以 简单快速地开发出SOAP/XML的服务器端和客户端 Step1 使用gsoap-2.8\gsoap\bin\win32\wsdl ...

  6. android客户端向java服务端post发送json

    android 端: private void HttpPostData() {        try { HttpClient httpclient = new DefaultHttpClient( ...

  7. “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX

    "快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...

  8. thrift例子:python客户端/java服务端

    java服务端的代码请看上文. 1.说明: 这两篇文章其实解决的问题是,当使用python去访问大数据线上集群的时候,遇到两个问题: 1)python-hadoop和python-hive相关包链接不 ...

  9. java版gRPC实战之六:客户端动态获取服务端地址

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. HDU1559 最大子矩阵 (二维树状数组)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1559 最大子矩阵 Time Limit: 30000/10000 MS (Java/Others)  ...

  2. 深入浅出JMS(二)--ActiveMQ简单介绍以及安装

    现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了消息通信的规范JM ...

  3. HTML5新的标签和属性

    <article>标签定义外部的内容.比如来自一个外部的新闻提供者的一篇新的文章,或者来自 blog 的文本,或者是来自论坛的文本.亦或是来自其他外部源内容. HTML5:<arti ...

  4. Java的算数运算符、关系运算符、逻辑运算符、位运算符

    JAVA的运算符,分为四类: 算数运算符.关系运算符.逻辑运算符.位运算符 算数运算符(9):+  -  *  /  %  ++  -- 关系运算符(6):==  !=  >  >=  & ...

  5. java.math.RoundingMode 几个参数详解

    java.math.RoundingMode里面有几个参数搞得我有点晕,现以个人理解对其一一进行总结: 为了能更好理解,我们可以画一个XY轴 RoundingMode.CEILING:取右边最近的整数 ...

  6. Java WebService 简单实例

    前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要的重复操作. 一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 ...

  7. JS动态引入js,CSS——动态创建script/link/style标签

    一.动态创建link方式 我们可以使用link的方式.如下代码所示. 二.动态创建style方式 但是,这样的话,需要加载整个css文件,但是那样有可能浪费一个http请求并占用一个服务器请求数,并等 ...

  8. JAVA实现复制文件夹

    package com.filetest; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...

  9. Thread-Safe Resource Manager

    http://php.net/manual/en/internals2.memory.tsrm.php When PHP is built with Thread Safety enabled, th ...

  10. 通过版本号实现乐观锁(MVCC)

    乐观锁大多是基于数据版本记录的机制实现 , 如 , 为每一行数据增加一个整型版本标识(version) , 每次数据更新都把版本号+1 工作原理:读取出数据时,将此版本号一同读出,之后更新时,对此版本 ...