我们先用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. HDU 1556 线段树或树状数组,插段求点

    1.HDU 1556  Color the ball   区间更新,单点查询 2.题意:n个气球,每次给(a,b)区间的气球涂一次色,问最后每个气球各涂了几次. (1)树状数组 总结:树状数组是一个查 ...

  2. 实现倒计时功能js

    <p>系统将会在<strong id="endtime"></strong>秒后跳转到登录页!</p> [原生js实现] <s ...

  3. MySQL数据备份之mysqldump使用

    mysqldump常用于MySQL数据库逻辑备份. 1.各种用法说明 A. 最简单的用法: mysqldump -uroot -pPassword [database name] > [dump ...

  4. JSP 简介

      160901   1. 一句话介绍什么是JSP? 和java相关的技术,可以开发出动态的,高性能的Web应用程序,的一门开发语言   2. 优点即特点,那么jsp的优点有哪些呢? JSP实现的We ...

  5. IOS网络第五天 AFN-01发送get和post请求

    ************AFN01-基本使用 #import "HMViewController.h" #import "AFNetworking.h" @in ...

  6. pict(Pairwise Independent Combinatorial Testing)工具使用

    PICT工具就是在微软公司内部使用的一款成对组合的命令行生成工具,现在已经对外提供,可以在互联网上下载到. 要把输入类型和其对应的参数输入到一个CSV格式(CSV: 以逗号分割的纯文本文件,不带有任何 ...

  7. java 启动 shell脚本

    run.sh p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #000000 ...

  8. reg

    <div class="login-module"> <div class="wide c login"> <form id=&q ...

  9. Android--ListView与数据绑定(Xamarin)

    ListView 控件是一个条目容器, 用于显示集合对象(如数组, List<T>, ObservableCollection<T>等)的每一个条目, 并提供滚动功能. 列表视 ...

  10. 关于新版ADT创建项目时出现appcompat_v7的问题

    做Android开发的朋友最近会发现,更新ADT至22.6.0版本之后,创建新的安装项目,会出现appcompat_v7的内容.并且是创建一个新的内容就会出现.这到底是怎么回事呢?原来appcompa ...