客户端使用java,服务端使用c++的corba编程环境搭建
我们先用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编程环境搭建的更多相关文章
- C#使用Thrift简介,C#客户端和Java服务端相互交互
C#使用Thrift简介,C#客户端和Java服务端相互交互 本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实 ...
- RPC学习--C#使用Thrift简介,C#客户端和Java服务端相互交互
本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实现Client和Server C#服务端,Java客户端 其中 ...
- Socket通讯-C#客户端与Java服务端通讯(发送消息和文件)
设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能. Java服务端设计 packag ...
- Unity3D客户端和Java服务端使用Protobuf
转自:http://blog.csdn.net/kakashi8841/article/details/17334493 前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖 ...
- C++客户端访问Java服务端发布的SOAP模式的WebService接口
gSOAP是一个绑定SOAP/XML到C/C++语言的工具,使用它可以 简单快速地开发出SOAP/XML的服务器端和客户端 Step1 使用gsoap-2.8\gsoap\bin\win32\wsdl ...
- android客户端向java服务端post发送json
android 端: private void HttpPostData() { try { HttpClient httpclient = new DefaultHttpClient( ...
- “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX
"快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...
- thrift例子:python客户端/java服务端
java服务端的代码请看上文. 1.说明: 这两篇文章其实解决的问题是,当使用python去访问大数据线上集群的时候,遇到两个问题: 1)python-hadoop和python-hive相关包链接不 ...
- java版gRPC实战之六:客户端动态获取服务端地址
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- event
当一个事件被调用后,它会收到一个参数,第一个参数就是事件对象,事件对象包含type, target, timestamp三个. 类型:事件的名称,例如:点击目标:事件的目标元素时间戳:事件触发的时间
- ARM大学计划全球经理到访华清远见,深入交流教育合作
来源:华清远见嵌入式学院 10月20日,ARM大学计划全球经理Khaled Benkrid,高级内容主编洪川博士在ARM大学计划亚太经理陈炜博士的陪同下到访华清远见,就最新嵌入式技术.ARM处理器在教 ...
- 《bootstrap》实战---作为了解
感觉这句话说的挺有道理,"一些最佳实践不管是语义标记还是移动优先的设计,抑或资源性能优化,都需要额外的时间和精力才能时间".用心做,才会做好.
- C指针-const char* p到底是什么不可以改变
char a = 'w'; char b = 'q'; const char* p = &a; p = &b; printf("%c",p[0]); 如上一段代码, ...
- Proguard参数
参数:?-include?{filename}?从给定的文件中读取配置参数?-basedirectory?{directoryname}?指定基础目录为以后相对的档案名称?-injars?{class ...
- 史上自定义 JavaScript 函数Top 10
http://www.dustindiaz.com/top-ten-javascript/ 发布:wpulog | 发布时间: 2010年4月9日 10个被使用的最普遍的用户自定义函数,add ...
- [转]10个有关RESTful API良好设计的最佳实践
Web API已经在最近几年变成重要的话题,一个干净的API设计对于后端系统是非常重要的. 通常我们为Web API使用RESTful设计,REST概念分离了API结构和逻辑资源,通过Http方法GE ...
- 安装GIT,集成到Powershell中
1.首先安装GIT http://msysgit.github.io 下载最新版,然后安装.没什么好说的. 装完之后,把 安装路径/bin 加入到环境变量的Path中 2.删除Git的右键菜单 安装完 ...
- SQL常用代码段
--STUFF 函数将字符串插入另一字符串.它在第一个字符串中从开始位置删除指定长度的字符:然后将第二个字符串插入第一个字符串的开始位置. STUFF ( character_expression , ...
- SET QUOTED_IDENTIFIER ON和SET ANSI_NULLS ON
distinct是sqlserver的标识符,如果想以distinct为表时,在QUOTED_IDENTIFIER为off的情况下,是不能创建表名为distinct的表的,因为在QUOTED_IDEN ...