万星星@豌豆荚 欢迎加入我们
一个吃软饭的男人!!!!!我只想写程序####
微博:http://weibo.com/wanlianwen
posts - 172,  comments - 1253,  trackbacks - 0

学习 COM 的时候,一直强调 COM 的位置透明,但是始终感觉不到透明,组件都是本机注册的。知道分布式 COM 其实就是 DCOM 可以实现远程调用组件,但是一直懒于看,迟迟没有很好理解。眼看着分布式软件设计这么流行, .NET 、 J2EE 大行其道,横下心先把 DCOM 拿下。至于 DCOM 好处我不多说,上网 google 一下,最大的缺点是配置麻烦,尤其是存在防火墙的时候更麻烦(网上说的,我没有防火墙,呵呵)。

简单介绍 

从这个图看看客户端和服务器端分别需要什么(由于开始没有理解,客户端接口查询老失败,花费我半天时间)

客户端:客户程序、代理 / 存根

服务器端:服务器组件、代理 / 存根

这里可以看出 DOM 是针对 COM 远程调用( RPC )的实现,封装了底层通信。有些程序开发就是在使用 Socket DCOM 之间选择。

 

一个 DCOM 程序实现

实现一个简单的功能: DCOM 组件提供一个接口方法获取欢迎信息,客户端调用接口获取信息并显示。

创建 DCOM 组件

打开 VC6 ,首选创建一个 ATL 工程 DComServer

选择完成。

添加一个 ATL 组件,取名 Server ,添加一个接口方法:

实现方法:

STDMETHODIMP CServer::GetInfo(BSTR  * pbstrInfo)
{
       
//  TODO: Add your implementation code here
        if (pbstrInfo)
       
{
              
* pbstrInfo  =  SysAllocString(L " 你好,这里是DCOM服务器! " );
       }

       
return  S_OK;
}

打开Settings,进行工程设置:

编译可以发现项目目录下面生成了 DComServerps.dll ,这个就是代理存根,需要在客户和服务器注册。

创建客户端调用(一个基于对话框的 MFC 程序) (记的要初始化 COM 库)

实现连接和获取消息按钮事件:

void  CDComClientDlg::OnButtonConnect() 
{
    
//  TODO: Add your control notification handler code here
    COSERVERINFO    serverInfo;
    MULTI_QI        multiQi        
=   { & IID_IServer, NULL, NOERROR} ;
    HRESULT            hr            
=  NOERROR;
    UpdateData(TRUE);
    
//  如果已经连接上
     if (m_pIServer)
    
{
        m_pIServer
-> Release();
        m_pIServer 
=  NULL;
    }

    ZeroMemory(
& serverInfo,  sizeof (COSERVERINFO));
    serverInfo.pwszName 
=  m_strServer.AllocSysString();
    
//  创建远程组件
    hr  =  CoCreateInstanceEx(
        CLSID_Server,
        NULL,
        CLSCTX_REMOTE_SERVER,
        
& serverInfo,
        
1 ,
        
& multiQi);
    
//  释放字符串指针
    SysFreeString(serverInfo.pwszName);
    
if (SUCCEEDED(hr))
    
{
        m_pIServer 
=  (IServer * )multiQi.pItf;
        AfxMessageBox(_T(
" 连接成功! " ));
    }

    
else
    
{
        AfxMessageBox(_T(
" 连接失败! " ));
    }

}


void  CDComClientDlg::OnButtonGetmessage() 
{
    
//  TODO: Add your control notification handler code here
    BSTR    bstrInfo;
    USES_CONVERSION;
    
if (m_pIServer)
    
{
        m_pIServer
-> GetInfo( & bstrInfo);
        AfxMessageBox(W2A(bstrInfo));
    }

    
else
    
{
        AfxMessageBox(_T(
" 请连接DCOM服务! " ));
    }

}

 

部署客户端

这个地方有网上说很麻烦,需要关闭防火墙、需要用户名一致等,不过我还好,服务器是 Win2k sp4 administrator 帐户,客户端是 Win2k3 sp1 administrator 帐户,一次性就可以创建远程组件,就是查询接口时候老是失败。花了半天时间上网才发现需要注册代理存根 dll ,就是编译 DComServer 之前需要设置的。

拷贝 DComServer 下的 DComServerps.dll DComClient Debug 里面的 DComClient.exe 到客户端,使用 regsvr32 注册 DComServerps.dll ,运行 DComClient.exe

连接 DCOM 服务:

服务器进程自动启动:

获取消息:

 
代码下载。(里面有说明)

 

posted on 2006-07-10 11:25 万连文 阅读(2661) 评论(8)  编辑 收藏 引用 所属分类: ATL

FeedBack:
# re: 分布式设计之DCOM实现
2006-07-10 18:58 | LOGOS
汗.你要用RPC的话,用web service比DCOM好多了.  回复  更多评论
  
# re: 分布式设计之DCOM实现
2006-07-14 00:07 | hi
兄弟,dcom微软已经不再进行后期研发维护了,都改com+,Dot Net呢!  回复  更多评论
  
# re: 分布式设计之DCOM实现
2006-07-14 10:08 | 万连文
谢谢以上两个兄弟对我的友情提示,我知道技术越用越简单,我觉得自己应该一步一个脚印走过去,很难说.NET技术底层实现思想很大超越COM。  回复  更多评论
  
# re: 分布式设计之DCOM实现
2007-03-18 10:58 | 小桥
.NET本身就是个COM  回复  更多评论
  
# re: 分布式设计之DCOM实现
2007-03-18 10:59 | 小桥
望交流,QQ:2220911  回复  更多评论
  
# re: 分布式设计之DCOM实现
2008-07-07 12:03 | liyongcheng
客户端传递给服务器一个字符串怎么实现。


  回复  更多评论
  
# re: 分布式设计之DCOM实现
2008-07-07 23:07 | lwan
服务器添加一个接口传递字符串应该就可以了吧  回复  更多评论
  
# re: 分布式设计之DCOM实现
2011-12-05 12:53 | lhh
DCOM 跨机访问总是出权限问题, CoCreateInstanceEx返回ACCESSDENIED,请问该如何解决?  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


简历下载
联系我

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(66)

随笔分类

随笔档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜