zoukankan      html  css  js  c++  java
  • 创建DCOM

    客户端代码

    // RemoteClient.cpp : Defines the entry point for the console application.
    file://

    #include 
    "stdafx.h" // added _WIN32_DCOM
    #include // get "cout"
    #include // get _com_error
    #include // get time_t

    // extract definitions from server project
    #include "..\RemoteServer\RemoteServer.h"
    #include 
    "..\RemoteServer\RemoteServer_i.c"

    // forward reference for status display method
    void ShowStatus( HRESULT hr );

    int main(int argc, char* argv[])
    {
     HRESULT hr; 
    // COM error code
     IGetInfo *pI; // pointer to interface

     
    // Get the server name from user
     char name[32];
     cout 
    << "Enter Server Name:" << endl;
     gets( name );
     _bstr_t Server 
    = name;

     
    // remote server info
     COSERVERINFO cs;
     
    // Init structures to zero
     memset(&cs, 0sizeof(cs));
     
    // Allocate the server name in the COSERVERINFO struct
     cs.pwszName = Server;

     
    // structure for CoCreateInstanceEx
     MULTI_QI qi[1];
     memset(qi, 
    0sizeof(qi));

     
    // initialize COM 
     hr = CoInitialize(0);
     ShowStatus( hr );

     
    // macro to check for success
     if (SUCCEEDED(hr))
      
    {
       
    // set a low level of security
       hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
       RPC_C_AUTHN_LEVEL_NONE, 
       RPC_C_IMP_LEVEL_IMPERSONATE,NULL, EOAC_NONE, NULL);

       
    // init security
       ShowStatus( hr );
      }


     
    if (SUCCEEDED(hr)) 
      
    {
       
    // Fill the qi with a valid interface
       qi[0].pIID = &IID_IGetInfo;

       
    // get the interface pointer
       hr = CoCreateInstanceEx( CLSID_GetInfo, // clsid NULL, 
          
    // outer unknown CLSCTX_SERVER, 
          
    // server context &cs, // server info 1, 
          
    // size of qi qi ); // MULTI_QI array
          ShowStatus( hr );
      }


     
    if (SUCCEEDED(hr))
      
    {
       BSTR bsName; 
    // Basic style string

       
    // Extract the interface from the MULTI_QI strucure
       pI = (IGetInfo*)qi[0].pItf;

       
    // Call a method on the remote server
       hr = pI->GetComputerName( &bsName );
       ShowStatus( hr );

       
    // Convert name to a printable string
       _bstr_t bst( bsName );
       cout 
    << "Server Name :" << bst << endl;

       
    // get time from remote computer
       time_t tt;
       hr 
    = pI->GetTimeT(&tt );
       ShowStatus( hr );

       
    // display time_t as a string
       cout << "Server Time :" << ctime( &tt ) << endl; 

       
    // Release the interface
       pI->Release();
      }


      
    // Close COM
      CoUninitialize();

      
    // Prompt user to continue
      cout << "Press ENTER to continue" << endl;
      getchar();

      
    return 0;
     }


     
    // Display detailed status information
     void ShowStatus( HRESULT hr )
      
    {
       
    if (SUCCEEDED(hr))
        
    {
         cout 
    << "OK" << endl;
        }

       
    else
        
    {
         
    // construct a _com_error using the HRESULT
         _com_error e(hr);
         
    char temp[32];

         
    // convert to hexidecimal string and display
         sprintf( temp, "0x%x", hr );
         cout 
    << "Error : " << temp << endl;

         
    // The hr as a decimal number
         cout << "Decimal : " << hr << endl;

         
    // show the 1st 16 bits (SCODE)
         cout << "SCODE : " << HRESULT_CODE( hr ) << endl;
         
    // Show facility code as a decimal number
         cout << "Facility: " << HRESULT_FACILITY( hr ) << endl;
         
    // Show the severity bit
         cout << "Severity: " << HRESULT_SEVERITY( hr ) << endl;
         
    // Use the _com_error object to format a message string. This is 
         
    // Much easier then using ::FormatMessage
         cout << "Message : " << e.ErrorMessage() << endl; 
        }

      }


    相对于DCOM的创建,一个明显的改动是我们指定了服务器计算机的名字。以下就是我们必须加入到客户端的东西:

      。指定服务器计算机名字的方法。它将载入到COSERVERINFO结构体

      。调用CoCreateInstanceEx()代替CoCreateInstance()。这将包括有一些不同的参数和一个称为MULTI_QI的结构体

    通过COSERVERINFO指定服务器

      进行远程DCOM连接时,你必须指定服务器计算机的名字。计算机的名字可以是一个标准的UNC计算机名字或者是一个TCP/IP地址。我们将要求用户输入计算机的名字。我们的例子是一个控制台应用,因此我们将使用一个简单的输入流(include )来得到用户的输入并显示信息。

      
    // Get the server name from user
      char name[32];
      cout << "Enter Server Name:" << endl;
      gets( name );

      该服务器的名字将会被载入到一个COSERVERINFO结构体中。这个结构体需要一个指向宽字符(wide-character)的指针以得到服务器的名字。我们将使用_bstr_t copy构造器来转换该字符,在与BSTRs和宽字符配合时,_bstr_t是一个很有用的类。要注意到COSERVERINFO结构体会通过memset()函数初始化为0。

    // remote server info
    COSERVERINFO cs;
    // Init structures to zero
    memset(&cs, 0, sizeof(cs));
    // Allocate the server name in the COSERVERINFO struct
    // use _bstr_t copy constructor
    cs.pwszName = _bstr_t(name);

      通过MULTI_QI指定接口

      我们一般通过调用CoCreateInstance得到一个接口指针。对于DCOM来说,我们需要使用扩展的版本CoCreateInstanceEx。这个扩展的函数对于本地的COM服务器调用也是适用的。CoCreateInstanceEx有几个重要的区别。首先,它可让你指定服务器的名字;第二,通过一次调用,它可让你得到超过一个的接口。

      我们已经设置好COSERVERINFO结构体。我们将把它传送到CoCreateInstanceEx以指定服务器(如果你将该参数设置为NULL,你将使用本地的计算机)。

      以一般的版本不同,CoCreateInstanceEx可一次返回超过一个接口。它通过传送MULTI_QI结构体的一个数组来做到这一点。数组的每个元素指定了一个单一的接口。CoCreateInstanceEx将会填入到数据请求中。

    // structure for CoCreateInstanceEx
    MULTI_QI qi[2];
    // Array of structures
    // set to zero
    memset(qi, 0, sizeof(qi));

    // Fill the qi with a valid interface
    qi[0].pIID = &IID_IGetInfo;
    qi[1].pIID = &IID_ISomeOtherInterface;

    // get the interface pointer
    hr = CoCreateInstanceEx(
    CLSID_GetInfo, // clsid
    NULL, // outer unknown
    CLSCTX_SERVER, // server context
    &cs, // server info
    2, // size of qi
    qi ); // MULTI_QI array

    ......

    剩余的代码只是一般的COM客户代码。一旦你连接到服务器,DCOM的代码就没有什么特别的。

    在远程连接中,命名解析是一个恼人的问题。大部分人都想直接使用“\\RAOUL”或者“\\SERVER”的名字进行工作,而不是TCP/IP地址。将可读的名字转换为一个网络地址的过程就称为命名解析,在某些系统配置上,它可能是非常复杂的。一个简单的解决办法是通过服务器的TCP/IP地址来访问它。这将可以消除许多命名解析问题--这个问题已经超出了本文的讨论。在COSERVERINFO结构体中,你可以使用TCP/IP地址来代替标准的计算机名字。

    你也可以从TRACERT(跟踪路由)工具中得到有趣的信息。如果你有一个复杂的网络配置,跟踪结果可能是:

       C:\> TRACERT www.iftech.com

       Tracing route to www.iftech.com 216.27.33.21

       over a maximum of 30 hops:

       1 184 ms 169 ms 182 ms ct1.intercenter.net [207.211.129.2]

       2 182 ms 189 ms 188 ms ts-gw1.intercenter.net [207.211.129.1]

       3 195 ms 192 ms 161 ms ilan-gw1.intercenter.net [207.211.128.1]

       4 220 ms 178 ms 206 ms 206.152.70.33

       5 188 ms 207 ms 216 ms 207.211.122.2

       6 196 ms 189 ms 205 ms 216.27.1.71

       7 * * * Request timed out.

       8 201 ms 221 ms 197 ms rampart.iftech.com [216.27.12.142]

       9 210 ms 205 ms 192 ms www.iftech.com [216.27.33.21]

       Trace complete.

       C:\>

      就象你看到的,你的DCOM包到目的地的路由可以是很复杂的。

      要特别留意网关、路由器、代理和防火墙,因为它们经常会阻塞你的连接。特别是防火墙,因为它们经常会阻塞DCOM包,可与网络管理员一起检查一下。


    问题:不知道用vb是怎么来创建DCOM的?大家可以给我点建议吗?
  • 相关阅读:
    Solutions:Elastic SIEM
    Solutions:Elastic SIEM
    Solutions:Elastic SIEM
    Elasticsearch:设置Elastic账户安全
    Beats:通过Metricbeat实现外部对Elastic Stack的监控
    Kibana: 运用Data Visualizer来分析CSV数据
    Kibana:在Kibana中对数据进行深入分析
    Kibana:Canvas入门
    Elastic:创建你的第一个Elastic alert
    Elasticsearch:跨集群搜索 Cross-cluster search (CCS)
  • 原文地址:https://www.cnblogs.com/silva/p/277028.html
Copyright © 2011-2022 走看看