Windows RPC hello world

 

Rpc(Remote Procedure Call)远程过程调用定义创建分布式客户/服务端的强有力的开发技术。Rpc的运行的库管理大多数的网络通讯方面的细节,这就允许我们在实现时可以专注于我们的需求细节实现了。

我先来建立一个具有代表性的例子,然后在后序的的章节里写出我进一步的理解,理解有误之处,希望大家指出,共同学习、交流、进步。我的一个网友有一句话,常常影响着我,一个人不怕被人指出错误,可怕的就是到死依然不知错了。

计算机语言的大多数教程都使用着一个HellodWorld的经典例子作为初学者的入门写作,这里也来看一下类似的HelloWorld的例子是如何实现的,还是让我先给出一个单机版的例子先:

// Hello.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

void HelloWorld()

{

     printf("%s"n","Hello World!");

}

int _tmain(int argc, _TCHAR* argv[])

{

     HelloWorld();

     return 0;

}

这样我们就完成了一个单机版的HelloWorld的程序了。功能简单,实现容易,但是富有很大的代表性。说明了程序的结构,所以也常作为入门的一个例子。

用Rpc来实现这个例子没有这第简单的了,不过也不是很复杂,下面我就把我建立这个程序的步骤写下来。供大家参考。

第一步:建立好服务器和客户端交互通讯的定义,然后客户端按照这个说明去使用定义的功能,而服务端就要按照这个约定去完成这个功能。在远程调用过程中,RPC库管理着和通讯的很多工作了,故我们可以专注我们的实现。这些文件是一种IDL文件,它和传统的C语言有着非常相仿。例子如下

[

uuid(7a98c250-6808-11cf-b73b-00aa00b677a7),//接口标识

//endpoint("ncacn_ip_tcp:[23225]"),//远端

    version(1.0),//版本

//pointer_default(unique)]//处理指针的缺省为可空的指针

]   //接口头部,指定了这个接口的一些属性,uuid是不可省的。

interface Hello

{

void Hello ();

}

这样就定义这个交互的标准了,再运行下面这个命令得到我们最终想要的代理,存根和标准通讯的文件。

 Midl hello.idl

这样就会在同目录下生成如下的文件hello.h,hello_c.c,hello_s.c文件

第二步:建立客户端。

     建立一个工程,加入hello.h hello_c.c文件。并要链入rpcrt4.lib库文件。

#include <stdlib.h>
#include 
<stdio.h>
#include 
<ctype.h>
#include 
"hello.h" 
 
void main()
{
    RPC_STATUS status;
    unsigned 
char * pszUuid             = NULL;
    unsigned 
char * pszProtocolSequence = "ncacn_np";
    unsigned 
char * pszNetworkAddress   = NULL;
    unsigned 
char * pszEndpoint    = "\\pipe\\hello";
    unsigned 
char * pszOptions          = NULL;
    unsigned 
char * pszStringBinding    = NULL;
    unsigned 
char * pszString      = "hello, world";
    unsigned 
long ulCode;
 
    status 
= RpcStringBindingCompose(pszUuid,
                                     pszProtocolSequence,
                                     pszNetworkAddress,
                                     pszEndpoint,
                                     pszOptions,
                                     
&pszStringBinding);
    
if (status) 
    
{
        exit(status);
    }

    status 
= RpcBindingFromStringBinding(pszStringBinding,
                                         
&hello_IfHandle);
 
    
if (status) 
    
{
        exit(status);
    }

 
 
    RpcTryExcept  
    
{
        
        Hello();
          
    }

    RpcExcept(
1
    
{
        ulCode 
= RpcExceptionCode();
        printf(
"Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
    }

    RpcEndExcept
 
    status 
= RpcStringFree(&pszStringBinding); 
 
    
if (status) 
    
{
        exit(status);
    }

 
    status 
= RpcBindingFree(&hello_IfHandle);
 
    
if (status) 
    
{
        exit(status);
    }

 
    exit(
0);
 
}
  // end main()


/******************************************************/
/*         MIDL allocate and free                     */
/******************************************************/
 
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
    
return(malloc(len));
}

 
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
    free(ptr);
}


第三步:建立服务端。

建立一个工程,加入hello.h hello_s.c,链入rpcrt4.lib. 并要实现hello函数。

#include <stdlib.h>
#include 
<stdio.h>
#include 
<ctype.h>
#include 
"hello.h"
 
void main()
{
    RPC_STATUS status;
    unsigned 
char * pszProtocolSequence = "ncacn_np";
    unsigned 
char * pszSecurity     = NULL; 
    unsigned 
char * pszEndpoint    = "\\pipe\\hello";
    unsigned 
int    cMinCalls      = 1;
    unsigned 
int    cMaxCalls      = 20;
    unsigned 
int    fDontWait      = FALSE;
 
    status 
= RpcServerUseProtseqEp(pszProtocolSequence,
                                   cMaxCalls,
                                   pszEndpoint,
                                   pszSecurity); 
 
    
if (status) 
    
{
        exit(status);
    }

 
    status 
= RpcServerRegisterIf(hello_v1_0_s_ifspec,  
                                 NULL,   
                                 NULL); 
 
    
if (status) 
    
{
        exit(status);
    }

 
    status 
= RpcServerListen(cMinCalls,
                             cMaxCalls,
                             fDontWait);
 
    
if (status) 
    
{
        exit(status);
    }

 
 }
  // end main()
 
/******************************************************/
/*         MIDL allocate and free                     */
/******************************************************/
 
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
    
return(malloc(len));
}

 
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
    free(ptr);
}

void Hello()
{    
    printf(
"Hello world!");
}


虽然没有单机版的简单,但这个还是相当的简单的了,几步就做出了一个分布式的hello world.这个小例子是参照MSDN上写的.

 

posted @ 2007-08-26 20:15  Robert Xiao  阅读(740)  评论(0)    收藏  举报