zoukankan      html  css  js  c++  java
  • RCF进程间通信Demo程序

    在上一篇文章RPC通信框架——RCF介绍中,介绍了RCF的优点,本篇文章从头开始演示如何用RCF编写一个跨进程通信的Demo程序。

    将RCF编译为静态库

    从官网下载到的源码中包含一个RCF的项目,但是这项目是用来编译动态库的。可以参考这个项目来进行静态库的设置。

    首先创建一个空的项目文件,然后设置编译为静态库,添加源文件RCF.cpp,只需要这一个文件就够了,因为,这个文件里面,包含了其他所有的源文件。这种源代码的引用方式,编译为动态库,还可以接受,但是编译为静态库就会有一些问题,后面的文章中再讨论,不影响Demo的演示。

    然后添加预处理器:

    WIN32_LEAN_AND_MEAN
    _WIN32_WINNT=0x0500

    禁用特定警告(不是必须的):

    4275
    4251
    4510
    4511
    4512
    4127
    4702

    添加附加依赖项:

    ws2_32.lib

    这样就可以编译静态库了。

    Client、Server项目配置

    Client、Server的项目配置,首先是非常常见的引用RCF静态库的路径等配置,需要注意的一点就是需要添加如下预处理器:

    WIN32_LEAN_AND_MEAN
    _WIN32_WINNT=0x0500

    编写接口定义

    项目配置好后,需要添加Client、Server通信的功能,而他们通信是基于事先定义好的接口的,定义如下:

    #pragma once
    
    #include "rcf/rcf.hpp"
    #include <windows.h>
    #include <iostream>
    #include <string>
    using namespace std;
    
    RCF_BEGIN(I_HELLO, "I_HELLO")
        RCF_METHOD_V1(void, SayHello, const string&)
        RCF_METHOD_R1(int, add, int&)
        RCF_METHOD_V0(void, test)
    RCF_END(I_HELLO)

    编写接口的Server实现

    接口的定义是用来规定通信支持的功能,以及通信的协议。有了这些规定后,就需要来实现具体的功能,并且这是属于Server端的实现,Client端无需知道这些实现的细节,代码如下:

    #pragma once
    
    #include "rcf/rcf.hpp"
    #include <windows.h>
    #include <iostream>
    #include <string>
    using namespace std;
    #include "hello.h"
    
    class HelloImpl
    {
    public:
        void SayHello(const string& world)
        {
            cout << "hello " << world << endl;
        }
        int add(int& a)
        {
            a = a + a;
            return a + 2;
        }
        void test()
        {}
    };

    编写Server服务

    那么接下来,需要编写一个控制台或者Windows服务来承载此Server服务,这里就选择简单的控制台程序。

    RCF在Windows下支持三种通信协议:TCP、UDP、命名管道,

    此处我们选择TCP:

    #include "stdafx.h"
    #include "hello.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        RCF::RcfInitDeinit rcf_init;
        HelloImpl hello;
        RCF::RcfServer server(RCF::TcpEndpoint(50001));
        server.bind<I_HELLO>(hello);
        server.start();
    
        while(true)
        {
            Sleep(1000);
        }
    
        return 0;
    }

    如代码所示,在程序入口,需要通过RcfInitDeinit类的构造函数,进行RCF相关的初始化,程序退出时,通过RcfInitDeinit的析构函数进行RCF的清理工作。

    RCF初始化后,通过RcfServer的bind方法,绑定接口对应的具体实现,然后通过start方法启动服务。

    编写Client程序

    Client程序,在调用RCF相关方法之前,也需要通过RcfInitDeinit进行初始化工作,代码如下:

    #include "stdafx.h"
    #include "hello.h"
    #include "stop_watch.h"
    int _tmain(int argc, _TCHAR* argv[])
    {
        RCF::RcfInitDeinit rcf_init;
    
        RcfClient<I_HELLO> client(RCF::TcpEndpoint(50001));
        string str = "test";
        client.SayHello(str);
        int a = 3;
        int b = client.add(a);
        cout << "a = " << a << ", b = " << b << endl;
    
        stop_watch watch;
        watch.start();
        for (int i = 0; i < 20000; ++i)
        {
            client.test();
        }
        watch.stop();
        cout << watch.elapsed_ms() << " ms" << endl;
    
        return 0;
    }

    简单性能测试

    在我的笔记本 Windows7 专业版 SP1 x64 、Intel(R) Core(TM) i5-2450M CPU @ 2.5GHz、 12G内存 的机器上,通过此Demo,对RCF进行了测试。

    调用两万次,耗时1647ms左右,平均每秒可以调用12143次,平均每次调用耗时82微妙。

    计时工具——stop_watch

    计时工具 stop_watch类,可以参考C++高精度计时器——微秒级时间统计

    参考资料

    RCF User Guide

  • 相关阅读:
    1 . CentOS 7的yum更换为国内的阿里云yum源
    0. vagrant+vbox创建centos7虚拟机
    git上传到码云和下载到本地
    spring boot udp或者tcp接收数据
    你好,博客园
    使用firdder抓取APP的包
    初见loadrunner
    sublime快捷键大全
    html中行内元素与块级元素的区别。
    html.css溢出
  • 原文地址:https://www.cnblogs.com/hbccdf/p/rcf_demo.html
Copyright © 2011-2022 走看看