Windows本身支持成为一个RPC服务器。WindowsXP上面默认的RPC/tcpip功能没有打开,必须运行gpedit.msc,计算机配置->管理模版->系统->远程过程调用->用于未验证的RPC...->选择"已启动",限定项选择"无"。
第1步:编写 IDL(Interface Description Language,接口描述语言)文件
test.idl
[ uuid("9B26A55E-6DCD-4988-B83C-C6171F1DF5AC"), version(1.0) ] interface HelloWorld { // 我们定义的方法 int intAdd(int x, int y); }
一个可选的文件是应用程序配置文件(.acf),它的作用是对 RPC 接口进行配置:
test.acf
[ implicit_handle(handle_t test_Binding) ] interface HelloWorld { }
然后,会产生test.h、test_c.c、test_s.c几个文件,分别是头文件、客户端文件、服务器端文件。
第2步:编写服务器端程序
新建win32控制端程序,添加文件server.c:
#include<windows.h> #include <stdlib.h> #include <stdio.h> #include "test.h" int intAdd( int x, int y) { printf("%d + %d = %d\n", x, y, x+y); return x+y; } int main(int argc,char * argv[]) { // 采用tcp协议,13521端口 RpcServerUseProtseqEp((unsigned char *)"ncacn_ip_tcp", RPC_C_PROTSEQ_MAX_REQS_DEFAULT, (unsigned char *)"13521", NULL); // 注册,HelloWorld_v1_0_s_ifspec定义域头文件test.h RpcServerRegisterIf(HelloWorld_v1_0_s_ifspec, NULL, NULL); // 开始监听,本函数将一直阻塞 RpcServerListen(1,20,FALSE); return 0; } // 下面的函数是为了满足链接需要而写的,没有的话会出现链接错误 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); }
test.h、test_s.c这2个文件也添加到server工程中。
然后,编译,即可运行。
第3步:编写客户端程序
同样地,建立一个工程client。
在菜单“工程”——“设置”——“链接”——“对象模块”中,添加rpcrt4.lib。
test.h、test_c.c这2个文件也添加到client工程中。
添加源文件client.c:
#include <windows.h> #include <stdlib.h> #include <stdio.h> #include "test.h" int main() { unsigned char * pszStringBinding = NULL; int x, y, rval; RpcStringBindingCompose( NULL, (unsigned char*)"ncacn_ip_tcp", (unsigned char*)"localhost" /*NULL*/, (unsigned char*)"13521", NULL, &pszStringBinding ); // 绑定接口,这里要和 test.acf 的配置一致,那么就是test_Binding RpcBindingFromStringBinding(pszStringBinding, & test_Binding ); // 下面是调用服务端的函数了 RpcTryExcept { while(1) { printf("Input two integer: "); scanf("%d %d", &x, &y); rval = intAdd(x, y); printf("%d\n", rval); } } RpcExcept(1) { printf( "RPC Exception %d\n", RpcExceptionCode() ); } RpcEndExcept // 释放资源 RpcStringFree(&pszStringBinding); RpcBindingFree(&test_Binding); return 0; } // 下面的函数是为了满足链接需要而写的,没有的话会出现链接错误 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); }
程序功能:
在client中,输入2个整数,那么server会计算其和,并返回。