您的位置:首页 > 编程语言

Windows RPC编程入门(已动手实践按红体字部分修改可以正常运行)

2013-08-05 23:09 489 查看
Windows本身支持成为一个RPC服务器。MSDN里面有个很好的例子,但是,WindowsXP上面默认的RPC/tcpip功能没有打开,必须运行gpedit.msc,计算机配置->管理模版->系统->远程过程调用->用于未验证的RPC...->选择"已启动",限定项选择"无"。用VC2010express建立两个工程,按照MSDN的例子:

首先,idl文件my.idl:

[

  uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),

  version(1.0)

]

interface hw // The interface is named hw

{

   // A function that takes a zero-terminated string.

   void Hello(

      [in, string] const
 char* szOutput);

}

编译以后,相应的文件放到服务器端和客户端程序里面去。

服务器端实现:

#include"stdafx.h"

#include<stdio.h>

#include<stdlib.h>

#include"my_h.h"

#pragma comment(lib,"rpcrt4")

#pragma comment(lib,"ole32")

extern "C"{

void Hello(handle_t IDL_handle,const unsigned char*psz){

    printf("server:%s\n",psz);

}

void Shutdown(handle_t IDL_handle){

    RpcMgmtStopServerListening(NULL);

    RpcServerUnregisterIf(NULL,NULL,FALSE);

}

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);

}

}

int main()

{

   RPC_STATUS status;

   status = RpcServerUseProtseqEp(

      (RPC_CSTR)("ncacn_ip_tcp"), //
 Use TCP/IP protocol.

      RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue length for TCP/IP.

      (RPC_CSTR)("4747"), //
 TCP/IP port to use.

      NULL); //
 No security.

   if (status){

       printf("ServerUse failed\n");

       exit(status);}

   else printf("UseProtseqEq
 ok\n");

   status = RpcServerRegisterIf(

      hw_v1_0_s_ifspec, // Interface to register.

      NULL, // Use the MIDL generated entry-point vector.

      NULL);//
 Use the MIDL generated entry-point vector.

   if (status){

       printf("Register failed\n");

       exit(status);}

   else printf("Register
 if ok\n");

   // This call will not return until

   // RpcMgmtStopServerListening is called.

   status = RpcServerListen(

     1, // Recommended minimum number of threads.

     RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.

     FALSE); //
 Start listening now.

   if (status){

       printf("Server listen failed\n");

       exit(status);}

   else printf("listen
 ok\n");

   return 0;

}

启动以后显示:

UseProtseqEq ok

Register if ok

客户端代码:

// myclient.cpp : Defines the entry point for the console application.

#include"stdafx.h"

#include<windows.h>

#include<stdio.h>

#include"my_h.h"

#pragma comment(lib,"rpcrt4")

#pragma comment(lib,"ole32")

int main(void){

    RPC_STATUS status;

    RPC_BINDING_HANDLE hwBinding;

    unsigned char* szStringBinding=NULL;

    status=RpcStringBindingCompose(//建立一个String Binding句柄,并不连接

        NULL,

        (RPC_CSTR)("ncacn_ip_tcp"),

        (RPC_CSTR)("localhost"),

        (RPC_CSTR)("4747"),

        NULL,

        (RPC_CSTR*)&szStringBinding);

    if(status){

        printf("StringBinding failed\n");

        exit(status);}

    printf("szString=%s\n",szStringBinding);

    status=RpcBindingFromStringBinding(

        szStringBinding,

        &hwBinding);

    if(status){

        printf("Bind from String failed:%d\n",GetLastError());

        exit(status);}

    RpcTryExcept{

                Hello(hwBinding,(RPC_CSTR)("Hello
 RPC World!"));

   }

   RpcExcept(1){

      printf("Runtime reported exception:%d,except=%d\n",GetLastError(),RpcExceptionCode()/*RPC_S_ACCESS_DENIED==5L*/);//这里返回了5

   }

   RpcEndExcept

   status = RpcBindingFree(&hwBinding); //
 Frees the binding handle.

   if (status){

       printf("Bind free failed\n");

       exit(status);}

    return 0;

}

void* __RPC_USER midl_user_allocate(size_t size){

    return malloc(size);

}

// Memory deallocation function for RPC.

void __RPC_USER midl_user_free(void* p){

    free(p);

}

运行显示:

szString=ncacn_ip_tcp:localhost[4747]

此时,服务器端显示:

server:Hello RPC World!

多次启动客户端,上面这句话显示多次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐