• 安全传输平台项目扩展——C复习-C++复习-keymngclient重构


    在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    11-安全传输平台项目扩展-第01天(C复习-C++复习-keymngclient重构)

    目录:
    一、课程目标
    二、安全传输平台项目扩展——C复习-C++复习
    1、C语言知识体系复习-两个模型
    2、C语言知识体系复习-指针做函数api实现
    3、C语言知识体系复习-模拟函数调用入栈出栈内存模型
    4、C语言知识体系复习-间接赋值的重要性和成立三个条件
    5、C++语言知识体系复习-多态理解1
    6、C++语言知识体系复习-多态理解2
    7、C++语言知识体系复习-C和C++横向比较
    8、C语言知识体系复习-回调函数
    9、C++面向抽象类编程思想回顾
    三、安全传输平台项目扩展——keymngclient重构
    1、项目需求和方案
    2、C++类对象之间的关系-依赖和关联
    3、密钥协商客户端业务流复习
    4、keymngclient设计与实现-思路
    5、keymngclient设计与实现-keymngclient的hello
    6、keymngclient设计与实现-LogHelper类
    7、keymngclient设计与实现-myipc类
    8、keymngclient设计与实现-KeyMng_ShmOp类
    9、keymngclient设计与实现-应用程序框架类和业务流类设计思想
    10、keymngclient设计与实现-keymngclientapp
    11、keymngclient设计与实现-keymngclientop
    12、keymngclient设计与实现-初始化流程编写
    13、keymngclient设计与实现-初始化流程调试
    14、keymngclient设计与实现-密钥协商编写和调试

    一、课程目标

    用C++重构安全传输平台

    深入理解C语言知识体系

    两个模型(函数调用、内存四区模型)
        指针做函数参数(一级指针、二级指针、三级指针;指针的输入和输出)
        函数指针做函数参数
        C语言项目开发理念:接口的封装和设计、模块之间解耦合

    深入理解C++语言知识体系
        封装、继承、多态
    项目开发中C++工具的应用    
        C++项目开发理念(面向抽象类编程)
    进一步理解安全传输平台secmngclient和secmngserver的业务模型
        用C++做开发常见套路

    二、安全传输平台项目扩展——C复习-C++复习

    1、C语言知识体系复习-两个模型

    》两个模型(函数调用、内存四区模型)

    示例:main函数调用fun1()函数,fun1()函数调用fun2()函数,fun2()函数调用fun3()函数:

    问题1:在函数main中分配的内存,在fun3()中能用吗?

    都能用

    问题2:在函数fun3()中分配的内存 在main函数中能用吗?

    内存  堆  栈  全局区(静态变量) 代码区——要看分配的内存在哪,全局和malloc(栈)得到的可以用

    》理念:输入和输出

    角度:站在被调用函数的调度去思考  函数1调用函数2

      输入:函数1调用函数2,在函数1中分配内存,供函数2使用

      输出:函数1调用函数2,在函数2中分配内存,供函数1使用

    2、C语言知识体系复习-指针做函数api实现

    》指针做函数参数(一级指针、二级指针、三级指针;指针的输入和输出)

    案例1:指针做函数参数

    需求:写一个接口 完成配置文件的读 要求一次性把N行数据 返给调用者

    >dm01_指针做函数参数.c

    #define _CRT_SECURE_NO_WARNINGS
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    
    
    //间接赋值成立的三个条件
    //条件1: 定义两个变量 (形参 实参)
    //条件2: 建立关联 若为函数调用 实参取地址 传给  形参 
    //条件3: 在被调用函数中  *p 实参的地址 去 间接的修改实参的值 
    //  用N级形参 去修改 N-1级实参的值
    
    //写一个接口 完成配置文件的读 要求一次性把N行数据 返给调用者
    int  getFileContent(char *pFileName/*in*/, char ***p, int *nLine)
    {
        char **tmpP = NULL;
        int        i = 0;
        tmpP = (char **)malloc(sizeof(char *)* 10);
        if (tmpP == NULL)
        {
            printf("func getFileContent() err: ");
            return -1;
        }
    
    
        for (i = 0; i < 10; i++)
        {
            tmpP[i] = (char *)malloc(20);
            sprintf(tmpP[i], "%d%d%d", i, i, i);
        }
    
        //间接赋值
        *p = tmpP;  //*p实参的地址 放在=的左边 去间接的修改 实参的值
        //*p1 = *p2;
        *nLine = 10;
        return 0;
    }
    
    int  getFileContent_Free(char **p, int iLine)
    {
        int i = 0;
        if (p == NULL)
        {
            return 0;
        }
    
        for ( i = 0; i < iLine; i++)
        {
            free(p[i]);
        }
    
        free(p);
        //p = NULL;
    
        return 0;
    }
    
    
    // 既可以把指针所指向的内存空间给释放掉 并且把实参重新赋值成NULLL
    int  getFileContent_Free2(char ***p, int iLine)
    {
        getFileContent_Free(*p, iLine);
        *p = NULL;
        return 0;
    }
    
    
    int main()
    {
        int        ret = 0, i = 0;
        char    *myFileName = "c:1.txt";
        char    **myP = NULL;
        int        myLine = 0;
    
        printf("hello...
    ");
    
        //获取文件内容
        ret = getFileContent(myFileName, &myP, &myLine);
        if (ret != 0)
        {
            printf("func getFileContent() err:%d 
    ", ret);
            return ret;
        }
    
        //打印文件内容 按照行
        for (i = 0; i < myLine; i++)
        {
            printf("%s
    ", myP[i]);
        }
    
    
        //getFileContent_Free(myP, myLine);
        getFileContent_Free2(&myP, myLine);
        system("pause");
        return 0;
    }
    dm01_指针做函数参数.c

    问题:为什么getFileContent_Free中释放完内存后不能p = NULL?

    直接修改p的值,时无法传给(main函数)实参的,所以getFileContent_Free2中*p实参的地址 放在=的左边可以去间接的修改 实参的值。为加深理解:譬如可以在main函数中通过myP=0x11直接修改实参的值,也可以通过*(&myP)=0x11间接修改实参的值,只不过是把*(&myP)=0x11放到被调用函数getFileContent_Free2中,而在被调用函数中getFileContent_Free使用(&myP)=0x11是无法修改实参的值的。所以在getFileContent_Free中修改p的值(p=NULL),与实参没有任何关系(更改不掉的),反而实参指向的空间因为没有了,会出现野指针。

    3、C语言知识体系复习-模拟函数调用入栈出栈内存模型

    》dm01_指针做函数参数.c 函数调用模型

    注意:变量的本质:门牌号(内存的标号)

    给变量赋值:给变量所代表的内存空间赋值。

    4、C语言知识体系复习-间接赋值的重要性和成立三个条件

    》间接赋值成立的三个条件

    条件1:定义两个变量 (形参 实参)
    条件2:建立关联 若为函数调用 实参取地址 传给  形参
    条件3:在被调用函数中  *p 实参的地址 去 间接的修改实参的值
    用N级形参 去修改 N-1级实参的值

    5、C++语言知识体系复习-多态理解1

    》多态成立的三个条件
    要继承、虚函数重写、父类指针(引用)指向子类对象
    效果:同一个调用语句 可以有多种形态(多种调用方法)

    多态的意义?要从3大理念看。
    》面向对象的三大理念  
    封装:类的对象做函数参数的角度1 突破了C语言函数的概念
    继承:可以使用老爹的东西
    多态:老爹可以使用后来人写的代码  可扩展 模块的解耦合

    》多态的现象: 同一个调用语句 可以有多种形态

    扔过来一个子类对象 执行子类API函数
    扔过来一个父类对象 执行父类API函数

    》C++编译器如何实现多态?

    1)提前布局 2)迟绑定(动态联编)

    说明:C++编译器为含有虚函数的类的对象提前布局vptr指针和虚函数表 ;在发生多态的时候 (虚函数调用的时候), 去虚函数表中查找调用地址(函数的入口地址);执行后来人写的代码。

    6、C++语言知识体系复习-多态理解2

    练习:dm02_多态理解.cpp

    #include <iostream>
    using namespace std;
    
    
    //多态成立的三个条件
    // 要继承  虚函数重写  父类指针(引用)指向子类对象 
    //效果: 同一个调用语句 可以有多种形态(多种调用方法)
    
    //多态的意义 
    //面向对象的三大理念  
    //封装    类的对象做函数参数的角度1 突破了C语言函数的概念
    //继承     可以使用老爹的东西 
    //多态    老爹可以使用后来人写的代码  可扩展 模块的解耦合
    
    //1 提前布局 2 迟绑定(动态联编)
    
    
    class MyParent
    {
    public:
        MyParent()
        {
            cout << "我是爹 构造" << endl;
        }
    public:
        virtual void print()
        {
            cout << "我是爹 working" << endl;
        }
    protected:
    private:
        int  a;
    };
    
    
    class MyChhild : public MyParent
    {
    public:
        MyChhild()
        {
            cout << "我是儿子 构造" << endl;
        }
    public:
        virtual void print()
        {
            cout << "我是儿子 working" << endl;
        }
    protected:
    private:
    };
    
    
    //10:35写
    class MyChhildChild : public MyChhild
    {
    public:
        MyChhildChild()
        {
            cout << "我是孙子 构造" << endl;
        }
    public:
        virtual void print()  //2
        {
            cout << "我是孙子 working" << endl;
        }
    protected:
    private:
    };
    
    
    //搭建一个舞台 让对象唱戏  10:20
    void howToPrintf(MyParent *base)
    {
        base->print();    //多态的现象: 同一个调用语句 可以有多种形态 //1
        //扔过来一个子类对象 执行子类API函数 
        //扔过来一个父类对象 执行父类API函数 
    
        //C++编译器为含有虚函数的类的对象提前布局vptr指针和虚函数表 ;在发生多态的时候 (虚函数调用的时候), 去虚函数表中查找调用地址(函数的入口地址)
        //执行后来人写的代码
    }
    
    int main()
    {
    
        MyParent   p1; //vptr指针  //虚函数表 
        MyChhild  c1;
        
    
        howToPrintf(&p1);
        howToPrintf(&c1);
    
        MyChhildChild   cc1;
        howToPrintf(&cc1);
    
    
        cout << "hello..." << endl;
        system("pause");
        return 0;
    }
    dm02_多态理解.cpp

    多态理念场景图:

    7、C++语言知识体系复习-C和C++横向比较

    C和C++都是面向接口的。

    8、C语言知识体系复习-回调函数

    需求:用C语言的语法实现多态?

    了解语法,练习:dm03_函数指针做函数参数.c

    #define _CRT_SECURE_NO_WARNINGS
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    
    //语法
    //如何理解函数指针做函数参数(你是如何理解回调函数)
    //语法层次上: 谁调用含有函数指针做函数参数的api函数 谁提供回调函数的入口地址
    //调用关系上: 本来你去调用框架 ,结果 框架反过来调用你的API函数  ,所以叫回调
    //好处:任务的调用者和任务的编写者解耦合
    
    int   myAdd(int a, int b)
    {
        int c = 0;
        c = a + b;
        return c;
    }
    
    
    int   myAdd2(int a, int b)
    {
        int c = 0;
        c = a + b;
        return c;
    }
    
    
    int   myAdd3(int a, int b)
    {
        int c = 0;
        c = a + b;
        return c;
    }
    
    //11:10
    int   myAdd4(int a, int b)
    {
        int c = 0;
        printf("func myAdd4() doing
    ");
        c = a + b;
        
        return c;
    }
    
    
    //搭建平台 框架 能调用后来人写的代码 11:05
    int MyFrameAdd(int (*myAddParam)(int a, int b),  int mya, int myb)
    {
        int c = myAddParam(mya, myb);
        printf("%d, ", c);  //间接调用
        return 0;
    }
    int main()
    {
        int mya = 10;
        int myb = 20;
        printf("直接调用 %d, ", myAdd(mya, myb));  //直接调用
        MyFrameAdd(myAdd4, 30, 40);
        printf("hello...
    ");
        system("pause");
        return 0;
    }
    dm03_函数指针做函数参数.c

    如何理解函数指针做函数参数(你是如何理解回调函数)?

    语法层次上: 谁调用含有函数指针做函数参数的api函数 谁提供回调函数的入口地址
    调用关系上: 本来你去调用框架 ,结果 框架反过来调用你的API函数  ,所以叫回调
    好处:任务的调用者和任务的编写者解耦合

    》回调函数模型:

    9、C++面向抽象类编程思想回顾

    》设计模式基本原则

      依赖倒置原则 (DIP,Dependence Inversion Principle)

    依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。

    (1)

    (2)

    练习:dm04_面向抽象类编程.cpp

    #include <iostream>
    using namespace std;
    
    class AbsMianBoard
    {
    public:
        virtual int doThing() = 0;
    
    protected:
    private:
    };
    
    class HSMainBoard : public AbsMianBoard
    {
    public:
        virtual int doThing()
        {
            cout << "华硕主板 工作...
    ";
            return 0;
        }
    
    protected:
    private:
    };
    
    class AbsCpu
    {
    public:
        virtual int doThing() = 0;
    
    protected:
    private:
    };
    
    class ARMCpu : public AbsCpu
    {
    public:
        virtual int doThing()
        {
            cout << "ARMCpu  工作...
    ";
            return 0;
        }
    
    protected:
    private:
    };
    
    //
    class AbsHardDisk
    {
    public:
        virtual int doThing() = 0;
    
    protected:
    private:
    };
    
    class XSDisk : public AbsHardDisk
    {
    public:
        virtual int doThing()
        {
            cout << "XSDisk  工作...
    ";
            return 0;
        }
    
    protected:
    private:
    };
    
    
    class Computer
    {
    public:
        Computer(AbsMianBoard    *absMainBoard,    AbsHardDisk    *absHardDisk,    AbsCpu    *absCpu)
        {
            m_absMainBoard = absMainBoard;
            m_absHardDisk = absHardDisk;
            m_absCpu = absCpu;
        }
    
        void doWork()
        {
            m_absMainBoard->doThing();
            m_absHardDisk->doThing();
            m_absCpu->doThing();
    
        }
    
    protected:
    private:
        AbsMianBoard    *m_absMainBoard;
        AbsHardDisk        *m_absHardDisk;
        AbsCpu            *m_absCpu;
    
    };
    
    
    int main()
    {
        AbsMianBoard    *absMainBoard = new HSMainBoard;
        AbsHardDisk    *absHardDisk = new XSDisk;
        AbsCpu    *absCpu = new ARMCpu;
    
    
        Computer     myComputer(absMainBoard, absHardDisk, absCpu);
        myComputer.doWork();
        cout << "hello..." << endl;
        system("pause");
        return 0;
    }
    dm04_面向抽象类编程.cpp

    三、安全传输平台项目扩展——keymngclient重构

    1、项目需求和方案

    需求回顾:

      app1、app2改动最小,最好是不改动
      保证密钥的安全分发
      网点的(对接入点做)生命周期的管理
      其他需求  性能  稳定

    》需求和方案回顾:

    2、C++类对象之间的关系-依赖和关联

    类与类之间的关系对于理解面向对象具有很重要的作用,以前在面试的时候也经常被问到这个问题,在这里我就介绍一下。

    》类与类之间存在以下关系:
    (1)泛化(Generalization)
    (2)关联(Association)
    (3)依赖(Dependency)
    (4)聚合(Aggregation)

    (1)依赖(虚线): 一个类是另外一个类的函数参数或者函数返回值 //案例:张三开车

    (2)关联(实线) 关联 张三 有车 一个类 是 另外一个类的成员变量 //案例:张三有车

    (3)聚合(菱形实线) : 整体和部分的关系 汽车 发动机 (汽车可以选择各个型号的发动机)

    (4)组合(实心形加实线) : 生命体,整体和部分的关系 汽车 发动机 (人 和 五脏六腑)

    3、密钥协商客户端业务流复习

    》SecMngclient和SecMngServer总体业务流设计

    4、keymngclient设计与实现-思路

    》secmngclient文件逻辑关系

    5、keymngclient设计与实现-keymngclient的hello

    (1)新建目录secmng,然后在secmng目录下拷贝makefile、新建inc目录和src目录,inc和src目录分别放置之前的头文件和源文件;

    (2)修改*.c为*.cpp(如:修改keymngclient.c文件名为keymngclient.cpp);修改*.h中ifdef..endif更改为#pragma once;然后更改keymngclient.cpp输入输出(先只输出hello)和头文件;

    (3)修改makefile(采用g++;目标文件改为.cpp;链接不需要的.o注释掉)

    (4)测试

    6、keymngclient设计与实现-LogHelper类

    (1)修改keymnglog.h,增加LogHelper类,然后把keymnglog.cpp中的函数和全局变量添加到LogHelper类中,做成员变量和成员函数(增加static关键字);修改头文件;

    (2)修改keymnglog.cpp,增加类的属性;

    (3)修改keymngclient.cpp中调用LogHelper类中成员函数;

    (4)修改makefile(增加链接的keymnglog.o);

    (5)make编译,然后执行>./keymngclient 测试

    7、keymngclient设计与实现-myipc类

    (1)修改myipc_shm.h,增加MyIpc_ShmHelper类,然后把myipc_shm.cpp中的函数和全局变量添加到MyIpc_ShmHelper类中,做成员变量和成员函数(增加static关键字);修改头文件;

    (2)修改myipc_shm.cpp,增加类的属性;

    (3)修改makefile(增加链接的myipc_shm.o);

    (4)make编译,然后执行>./keymngclient;测试

    (5)报错void *转换到int损失精度,所以更改为:long myTmp = reinterpret_cast<int>(tempptr);

    8、keymngclient设计与实现-KeyMng_ShmOp类

    (1)修改keymng_shmop.h,增加KeyMng_ShmOp类,然后把keymng_shmop.cpp中的函数和全局变量添加到KeyMng_ShmOp类中,做成员变量和成员函数(增加static关键字);修改头文件;

    (2)修改keymng_shmop.cpp,增加类的属性;

    (3)修改makefile(增加链接的keymng_shmop.o);

    (4)make编译,然后执行>./keymngclient;测试

    (5)报错IPC_Creatshm、IPC_Mapshm、IPC_UnMapShm在此作用域中尚未声明,keymng_shmop.cpp中所有相应的IPC_xxx前面作用域加上MyIpc_ShmHelper:: 

    (6)报错KyeMng_log在此作用域中尚未声明,keymng_shmop.cpp中所有的KyeMng_log前面作用域加上LogHelper:: 

    (7)报错void *型指针用在了算术表达式中,所以更改为:pNode = reinterpret_cast<NodeSHMInfo *>(reinterpret_cast<long>(mapaddr)+sizeof(NodeSHMInfo)*i );

    9、keymngclient设计与实现-应用程序框架类和业务流类设计思想

    主框架增加:设计应用程序类KeyMngClientApp和业务流类KeyMngClientOp;所以在keymngclient.cpp中主函数修改为:

    int main()
    {
        cout << "hello keymngclient...
    ";    
        /*
    KeyMngClientApp keyMngClientApp; KeyMngClientOp keyMngClientOp;
    //把业务流类对象 注入到 应用程序框架中 keyMngClientApp.setKeyMngClientOp(&keyMngClientOp); keyMngClientApp.init(); keyMngClientApp.run(); keyMngClientApp.exit(); */ return 0; }

    10、keymngclient设计与实现-keymngclientapp

    (1)拷贝keymngclient.cpp为keymngclientapp.cpp,拷贝keymngclient.cpp为keymngclientapp.h

    (2)keymngclientapp.h删除除头文件其他部分,并注释掉socket相关的头文件,然后设计KeyMngClientApp类:

    class KeyMngClientApp
    {
    public:
        KeyMngClientApp();
        ~KeyMngClientApp();
        
    public:int init();
        int run();
        int exit();    
    };

    (3)keymngclientapp.cpp中注释掉socket相关的头文件,增加输入C++头文件,实现KeyMngClientApp类中的成员函数(内部实现待写,都先写return 0);

    (4)修改makefile(增加链接的keymngclientapp.o);

    (5)keymngclient.cpp增加头文件 #include "keymngclientapp.h",主函数更改声明;

    (6)make编译,然后执行>./keymngclient;测试

    11、keymngclient设计与实现-keymngclientop

    (1)keymngclientop.h设计KeyMngClientOp类:

    class KeyMngClientOp
    {
    public:
        //初始化客户端 全局变量
         int MngClient_InitInfo(MngClient_Info *pCltInfo);
        
         int MngClient_Quit(MngClient_Info *pCltInfo);
        
         int MngClient_Agree(MngClient_Info *pCltInfo);
        
         int MngClient_Check(MngClient_Info *pCltInfo);
        
         int MngClient_Revoke(MngClient_Info *pCltInfo);
        
         int MngClient_view(MngClient_Info *pCltInfo);    
    };

    (2)keymngclientop.cpp中注释掉socket相关的头文件,成员函数增加类的属性,成员函数(内部实现待修改,都只留return 0,其他都注释掉);

    (3)修改makefile(增加链接的keymngclientop.o);

    (4)make编译,然后执行>./keymngclient;测试

    (5)keymngclientapp.h中KeyMngClientApp类中增加成员

    class KeyMngClientApp
    {
    public:
        KeyMngClientApp();
        ~KeyMngClientApp();
        
    public:
        int setKeyMngClientOp(KeyMngClientOp *keyMngClientOp);
        int init();
        int run();
        int exit();    
        
    public:    
        KeyMngClientOp        *m_keyMngClientOp;
    };

    (6)keymngclientapp.cpp中实现成员函数setKeyMngClientOp

    int KeyMngClientApp::setKeyMngClientOp(KeyMngClientOp *keyMngClientOp)
    {
        m_keyMngClientOp =  keyMngClientOp;
        return 0;
    }    

    (7)keymngclient.cpp主函数更改声明和调用;

    (8)make编译,然后执行>./keymngclient;测试

    12、keymngclient设计与实现-初始化流程编写

    keymngclientapp.cpp实现init函数:

    int KeyMngClientApp::init()
    {
        m_keyMngClientOp->MngClient_InitInfo(m_MngClientInfo);
        return 0;
    }

    由于MngClient_InitInfo(m_MngClientInfo)中使用到了m_MngClientInfo结构体,应该怎么分配内存呢?

    (1)keymngclient.cpp中增加api函数

    int main()
    {
        cout << "hello keymngclient...
    ";    
        KeyMngClientApp        keyMngClientApp;
        
        KeyMngClientOp        keyMngClientOp;
        
        MngClient_Info         mngClientInfo;
        
        
        //把业务流类对象 注入到 应用程序框架中
        keyMngClientApp.setKeyMngClientOp(&keyMngClientOp);
        keyMngClientApp.setMngClientInfo(&mngClientInfo);
        
        keyMngClientApp.init();
        keyMngClientApp.run();
        keyMngClientApp.exit();
                
        return 0;
    }

     (2)keymngclientapp.h中增加成员函数和成员变量:

    class KeyMngClientApp
    {
    public:
        KeyMngClientApp();
        ~KeyMngClientApp();
        
    public:
        int setKeyMngClientOp(KeyMngClientOp *keyMngClientOp);
        int setMngClientInfo(MngClient_Info *mngClientInfo);
        int Usage();
        int init();
        int run();
        int exit();    
        
    public:    
        KeyMngClientOp        *m_keyMngClientOp;
        MngClient_Info         *m_MngClientInfo;
    };

     (3)keymngclientapp.cpp实现成员函数setMngClientInfo;

    int KeyMngClientApp::setMngClientInfo(MngClient_Info *mngClientInfo)
    {
        m_MngClientInfo =  mngClientInfo;
        return 0;
    }    

    (4)keymngclientop.cpp更改MngClient_InitInfo函数中调用的函数的类作用域;

    (5)make编译,然后执行>./keymngclient;测试

    13、keymngclient设计与实现-初始化流程调试

    >gdb keymngclient

    调试后,在keymngclient.cpp中增加返回值判断

    int main()
    {
        int         ret = 0;
        cout << "hello keymngclient...
    ";    
        KeyMngClientApp        keyMngClientApp;
        
        KeyMngClientOp        keyMngClientOp;
        
        MngClient_Info         mngClientInfo;
        
        
        //把业务流类对象 注入到 应用程序框架中
        keyMngClientApp.setKeyMngClientOp(&keyMngClientOp);
        keyMngClientApp.setMngClientInfo(&mngClientInfo);
        
        ret = keyMngClientApp.init();
        if (ret != 0)
        {
            printf("keymngclient init err:%d 
    ", ret);    
            return ret;
        }
        printf("keymngclient init ok 
    ");    
        
        keyMngClientApp.run();
        keyMngClientApp.exit();
        
        
                        
        return 0;
    }

    14、keymngclient设计与实现-密钥协商编写和调试

    (1)keymngclientapp.cpp中实现成员函数Usage()、run();

    (2)keymngclientop.cpp中打开之前注释的密钥协商的函数MngClient_Agree(增加里边调用的函数的作用域,先注释掉日志调用);

    (3)make编译,然后执行>./keymngclient;测试

    (4)打开socket函数和头文件;

    (5)报错:poolsocket.h:5:错误:expected unqualified-id before 'C';poolsocket.h中第5行更改为extern "C"(注意:在linux下gcc中extern 'C'单引号没有问题,但是g++单引号会报错,需要更改为双引号extern "C"!!!)

    (6)打开另一个终端,启动原来C编写的服务器后台>./keymngserver,然后再原终端执行>./keymngclient;测试

    在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    后缀数组详解
    快速傅里叶变换详解(FFT)
    算法学习————SG函数和SG定理
    noi.ac七一模拟赛
    算法学习————高斯消元
    算法学习————Lucas定理
    算法学习————Kruskal重构树
    算法学习————FWT
    20210629模拟
    复习笔记之背包
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_SecureTransmissionPlatform_Project12.html
Copyright © 2020-2023  润新知