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的?大家可以给我点建议吗?
  • 相关阅读:
    【贪心】【堆】Gym
    【并查集】Gym
    【拓扑排序】【bitset】Gym
    【递归】【线段树】【堆】AtCoder Regular Contest 080 E
    【二分图】【并查集】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel
    【动态规划】【滚动数组】【bitset】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal
    【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix
    【枚举】【最小表示法】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game
    【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists
    【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures
  • 原文地址:https://www.cnblogs.com/silva/p/277028.html
Copyright © 2011-2022 走看看